SlideShare a Scribd company logo
Предметно-ориентированные
 языки программирования
                  Кириллов Александр, UNDEV
[ DSL ]
Предметно-ориентированный язык -

      это язык программирования с ограниченными
      выразительными возможностями,
      ориентированный на некую конкретную
      предметную область
                                   Мартин Фаулер
[ DSL ]
Зачем?
[ DSL ]
Зачем?
[ DSL ]
Зачем?




                          бк и...
                    ско
                эти
             уж
          Ох
[ DSL ]           BankAccount.configure do |account|
                    account.number 1234
                    account.type :checking
Зачем?    Ruby:
                    account.openDate '11.04.1974'
                    account.balance 25382.20
                    account.holder do |holder|
                      holder.lastName 'Singh'
                      holder.firstName 'Darshan'
                    end
                  end



                  BankAccount:
                    number: 1234
                    type: checking
                    open_date: '11.04.1974'
          YAML:     balance: 25382.20
                    account_holder:
                      last_name: Singh
                      first_name: Darshan
[ Ключевые моменты ]
Где и кто использует DSL?
[ Ключевые моменты ]
Где и кто использует DSL:
- конфигурации
# TravisCI config file (.yaml)
script: "bundle exec rake travis"
before_script: ./bin/ci/before_build.sh
services: mongodb
rvm:
  - 1.9.3
notifications:
  email:
     - didier@nocoffee.fr
     - mario@mariovisic.com
  irc: "irc.freenode.org#locomotivecms"
branches:
  only:
     - master
[ Ключевые моменты ]
Где и кто использует DSL:
- конфигурации
- зависимости пакетов
# Gemfile
source 'http://rubygems.org'

gem 'rails', '3.2.12'
group :assets do
  gem 'therubyracer'
  gem 'select2-rails', github: "argerim/select2-rails"
end
group :test do
  gem "minitest"
  gem 'mocha', require: false
end
[ Ключевые моменты ]
Где и кто использует DSL:
- конфигурации
- зависимости пакетов
- части фреймворков
# Sample resource route
resources :products do
  resources :comments
  resources :sales do
    get 'recent', on: :collection
  end
end
[ Ключевые моменты ]
Где и кто использует DSL:
- конфигурации
- зависимости пакетов
- части фреймворков
- системы тестирования
# Rspec example
describe Account do
  it "has a balance of zero when first created" do
    Account.new.balance.should eq(Money.new(0))
    expect { @a = 5 }.to change { @a }.from(nil).to(5)
  end
end
[ Ключевые моменты ]
Где и кто использует DSL:
- системы тестирования
 # language: ru
 Функционал: Сложение чисел
   Чтобы не складывать в уме
   Все, у кого с этим туго
   Хотят автоматическое сложение целых чисел

   Сценарий: Сложение двух целых чисел
     Допустим я ввожу число 50
     И затем ввожу число 70
     Если я нажимаю "+"
     То результатом должно быть число 120
[ Ключевые моменты ]
Где и кто использует DSL:
- и еще-еще-еще...
[ Ключевые моменты ]

Язык программирования
[ Ключевые моменты ]

Язык программирования

Декларативный подход
                        ЧТО делать
                        вместо

                        КАК делать
[ Ключевые моменты ]

Язык программирования

Декларативный подход

Природа языка
[ Ключевые моменты ]

Язык программирования

Декларативный подход

Природа языка

Ограниченные выразительные
возможности
[ Ключевые моменты ]

Язык программирования

Декларативный подход

Природа языка

Ограниченные выразительные
Возможности

Ориентированность на предметную область
[ Категории DSL ]

{
    Внутренний DSL: 'Lisp, Ruby, etc...',
}
[ Категории DSL ]

{
    Внутренний DSL: 'Lisp, Ruby, etc...',
    Внешний DSL: 'XML, RegExp, SQL, CSS'
}
[ Категории DSL ]

{
    Внутренний DSL: 'Lisp, Ruby, etc...',
    Внешний DSL: 'XML, RegExp, SQL, CSS',
    Языковые инструментальные средства: '*'
}
[ Реализация DSL ]
[ Реализация DSL ]
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)


 Применение обычного API:

 processor = Processor.new(arch: :i386, cores: 2)
 dsk1 = Disk.new(size: 150.GB, speed:7200)
 dsk2 = Disk.new(size: 70.GB, speed:7200)
 computer = Computer.new({
    processor: processor,
    disks: [dsk1, dsk2]
 })
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)


 Применение обычного API:


                                           ту
 processor = Processor.new(arch: :i386, cores: 2)
                                рограммис
 dsk1 = Disk.new(size: 150.GB, speed:7200) ти... ас
                         ятно п        етной обл
                  ...пон         пр дм
 dsk2 = Disk.new(size: 70.GB, еspeed:7200)
                           исту
                     ециал
 computer = Computer.new({
    processor:тно сп
           оня processor,
        неп[dsk1, dsk2]
    disks:
 })
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)

 Связывание методов:

 computer()
   .processor()
     .cores(2)
     .x64()
   .disk()
     .size(150)
     .speed(7200)
   .disk()
     .size(70)
     .speed(7200)
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)

 Связывание методов:

 $("#menu")
   .fadeIn('fast')
   .addClass("active")
   .css('marginRight', '10px');
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)

 Связывание методов:

 $("#menu")
   .fadeIn('fast')
   .addClass("active")
   .css('marginRight', '10px');

 $("#thumbnails li").mouseenter(function(e){
    $(this).find('img')
       .stop()
       .animate({opacity: 0.8}, 300)
    .end()
    .find('.viewcasestudy')
       .fadeIn('fast');
 }).fadeIn('fast');
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)
              Связывание методов
 Последовательность функций:

 computer()
 --processor()
 ----cores(2)
 ----x64()
 --disk()
 ----size(150)
 ----speed(7200)
 --disk()
 ----size(70)
 ----speed(7200)
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)
                             Связывание методов
              Последовательность функций
 Вложенные функции:

 computer(
 --processor(
 ----cores(2),
 ----x64()
 ––),
 --disk(
 ----size(150),
 ----speed(7200)
 ––),
 --disk(
 ----size(70),
 ----speed(7200)
 --)
 )
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)
                                    Связывание методов
                       Последовательность функций
              Вложенные функции
 Замыкания:
 ComputerBuilder.build do |c|
   c.processor do |p|
     p.cores 2
     p.x64
     p.speed 2.2
   end
   c.disk do |d|
     d.size 120
   end
   c.disk do |d|
     d.size 70
     d.speed 7200
     d.sata
   end
 end
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)

> Работа с синтаксическим деревом
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)

> Работа с синтаксическим деревом

> Аннотации
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)

> Работа с синтаксическим деревом

> Аннотации

> Макросы
[ Внутренний DSL ]
> Текучий интерфейс (fluent interface)

> Работа с синтаксическим деревом

> Аннотации

                  def method_missing(m, *args, &block)
> Макросы           puts "There's no method called #{m} here."
                  end

> Динамический отклик
[ Внешний DSL ]
> Синтаксический анализ
[ Внешний DSL ]
> Синтаксический анализ

Входной поток — это обычный текст (...обычно o_0)
[ Внешний DSL ]
> Синтаксический анализ

 Управляемая разделителями трансляция
 Delimiter-Directed Translation

 event door_opened
 event link_clicked
 event window_closed

 command play_music
 command volume_up 10
 command send_message "Hello, world"
[ Внешний DSL ]
> Синтаксический анализ

 Управляемая разделителями трансляция
 Delimiter-Directed Translation
                            разделитель
 event door_openedn
 event link_clicked
 event window_closed

 command play_music
 command volume_up 10
 command send_message "Hello, world"
             инструкция
[ Внешний DSL ]
> Синтаксический анализ

 Управляемая разделителями трансляция
 Delimiter-Directed Translation
                                    Ограничение:
 event door_opened
 event link_clicked
 event window_closed                Нет способов обработки
                                    иерархического контекста
 command play_music
 command volume_up 10
 command send_message "Hello, world"
[ Внешний DSL ]
> Синтаксический анализ

 Синтаксически управляемая трансляция
 Syntax-Directed Translation
                                             commands
 event                                         block
   door_opened
   link_clicked
 end                       command   commandDec   commandDec   end


 command
                                     play_music    volume_up   10
   play_music
   volume_up 10
   send_message "Hello, world"
 end
[ Внешний DSL ]
> Синтаксический анализ

Грамматика входного языка.




list            :   eventList    commandList        ;
eventList       :   'events'     eventDec*     'end';
eventDec        :   identifier                      ;
commandList     :   'commands'   commandDec*   'end';
commandDec      :   identifier   identifier?        ;
[ Внешний DSL ]
> Синтаксический анализ

Грамматика входного языка.

Форма Бэкуса-Наура


[E]BNF
list            :   eventList    commandList        ;
eventList       :   'events'     eventDec*     'end';
eventDec        :   identifier                      ;
commandList     :   'commands'   commandDec*   'end';
commandDec      :   identifier   identifier?        ;
[ Внешний DSL ]
> Синтаксический анализ

Синтаксический анализатор на основе
рекурсивного спуска
Recursive Descent Parser
[ Внешний DSL ]
> Синтаксический анализ

Комбинатор синтаксических анализаторов
Parser Combinator

                        Комбинатор
                          команд

    Анализатор                                  Анализатор
начала блока команд                         конца блока команд
                        Комбинатор
                       списка команд

          Анализатор                       Анализатор
           команды                     аргумента команды
[ Внешний DSL ]
> Синтаксический анализ

Генератор синтаксических анализаторов
Parser Generator


                     Генерация



 Грамматика
                                 Синтаксический
 a : ID INT ;                      анализатор
 ID : 'a'..'z'+ ;
 INT : '0'..'9'+;
[ Для чего все это? ]

В результате мы должны иметь
построенную семантическую модель
[ Для чего все это? ]

В результате мы должны иметь
построенную семантическую модель


> Для использования в программном продукте
[ Для чего все это? ]

В результате мы должны иметь
построенную семантическую модель


> Для использования в программном продукте

> Для генерации нового кода
[ Генерация кода ]

> Генерация c помощью преобразователя
  Transformer Generation
[ Генерация кода ]

> Генерация c помощью преобразователя
  Transformer Generation

> Шаблонная генерация
 Templated Generation
[ Генерация кода ]

> Генерация c помощью преобразователя
  Transformer Generation

> Шаблонная генерация
 Templated Generation

> Встроенный помощник
 Embedment Helper
[ Если Вы заинтересованы ]

                http://martinfowler.com/dslCatalog/
[ Спасибо за внимание! ]


     Кириллов Александр
       http://twitter.com/saratovsource

More Related Content

Similar to Предметно-ориентированные языки программирования (DSL)

Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...Dmitri Soshnikov
 
Использование Sedna в WEB
Использование Sedna в WEBИспользование Sedna в WEB
Использование Sedna в WEB
Alexandre Kalendarev
 
DSL без купюр
DSL без купюрDSL без купюр
DSL без купюр
Mikhail Shcherbakov
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NET
Positive Hack Days
 
PowerShell
PowerShellPowerShell
PowerShell
GetDev.NET
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application Development
Anton Kirillov
 
Big Data и Ruby
Big Data и RubyBig Data и Ruby
Big Data и Ruby
Александр Ежов
 
ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS
Pavel Tsukanov
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Ontico
 
Расширение библиотеки Slick
Расширение библиотеки SlickРасширение библиотеки Slick
Расширение библиотеки Slick
Арсений Жижелев
 
Console application with ZF 2.0
Console application with ZF 2.0Console application with ZF 2.0
Console application with ZF 2.0
Alexey Kachayev
 
So Your WAF Needs a Parser
So Your WAF Needs a ParserSo Your WAF Needs a Parser
So Your WAF Needs a Parser
yalegko
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорьdrupalconf
 
BIML - лучший друг для SSIS разработчика
BIML - лучший друг для SSIS разработчикаBIML - лучший друг для SSIS разработчика
BIML - лучший друг для SSIS разработчика
Andrey Korshikov
 
Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Ontico
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
Alexander Granin
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов ИгорьPVasili
 
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Magneta AI
 
Михаил Щербаков "WinDbg сотоварищи"
Михаил Щербаков "WinDbg сотоварищи"Михаил Щербаков "WinDbg сотоварищи"
Михаил Щербаков "WinDbg сотоварищи"
Mikhail Shcherbakov
 

Similar to Предметно-ориентированные языки программирования (DSL) (20)

Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...
 
Использование Sedna в WEB
Использование Sedna в WEBИспользование Sedna в WEB
Использование Sedna в WEB
 
DSL без купюр
DSL без купюрDSL без купюр
DSL без купюр
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NET
 
PowerShell
PowerShellPowerShell
PowerShell
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application Development
 
Big Data и Ruby
Big Data и RubyBig Data и Ruby
Big Data и Ruby
 
ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
 
Расширение библиотеки Slick
Расширение библиотеки SlickРасширение библиотеки Slick
Расширение библиотеки Slick
 
Console application with ZF 2.0
Console application with ZF 2.0Console application with ZF 2.0
Console application with ZF 2.0
 
So Your WAF Needs a Parser
So Your WAF Needs a ParserSo Your WAF Needs a Parser
So Your WAF Needs a Parser
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
BIML - лучший друг для SSIS разработчика
BIML - лучший друг для SSIS разработчикаBIML - лучший друг для SSIS разработчика
BIML - лучший друг для SSIS разработчика
 
Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
 
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
 
Михаил Щербаков "WinDbg сотоварищи"
Михаил Щербаков "WinDbg сотоварищи"Михаил Щербаков "WinDbg сотоварищи"
Михаил Щербаков "WinDbg сотоварищи"
 
DDOS mitigation software solutions
DDOS mitigation software solutionsDDOS mitigation software solutions
DDOS mitigation software solutions
 

More from Alexander Kirillov

Rom - Ruby Object Mapper
Rom - Ruby Object MapperRom - Ruby Object Mapper
Rom - Ruby Object Mapper
Alexander Kirillov
 
Окружение разработчика - от виртуализации к контейнеризации
Окружение разработчика - от виртуализации к контейнеризацииОкружение разработчика - от виртуализации к контейнеризации
Окружение разработчика - от виртуализации к контейнеризацииAlexander Kirillov
 
Polymer - New Era of Web Development
Polymer - New Era of Web DevelopmentPolymer - New Era of Web Development
Polymer - New Era of Web Development
Alexander Kirillov
 
Виртуализация как инструмент разработчика
Виртуализация как инструмент разработчикаВиртуализация как инструмент разработчика
Виртуализация как инструмент разработчикаAlexander Kirillov
 
Application deployment & configuration management
Application deployment & configuration managementApplication deployment & configuration management
Application deployment & configuration managementAlexander Kirillov
 
XSLT. Basic.
XSLT. Basic.XSLT. Basic.
XSLT. Basic.
Alexander Kirillov
 

More from Alexander Kirillov (9)

Rom - Ruby Object Mapper
Rom - Ruby Object MapperRom - Ruby Object Mapper
Rom - Ruby Object Mapper
 
Окружение разработчика - от виртуализации к контейнеризации
Окружение разработчика - от виртуализации к контейнеризацииОкружение разработчика - от виртуализации к контейнеризации
Окружение разработчика - от виртуализации к контейнеризации
 
Polymer - New Era of Web Development
Polymer - New Era of Web DevelopmentPolymer - New Era of Web Development
Polymer - New Era of Web Development
 
Виртуализация как инструмент разработчика
Виртуализация как инструмент разработчикаВиртуализация как инструмент разработчика
Виртуализация как инструмент разработчика
 
Application deployment & configuration management
Application deployment & configuration managementApplication deployment & configuration management
Application deployment & configuration management
 
XSLT. Basic.
XSLT. Basic.XSLT. Basic.
XSLT. Basic.
 
Securing Rails Applications
Securing Rails ApplicationsSecuring Rails Applications
Securing Rails Applications
 
Ruby gui
Ruby guiRuby gui
Ruby gui
 
I18n
I18nI18n
I18n
 

Предметно-ориентированные языки программирования (DSL)

  • 2. [ DSL ] Предметно-ориентированный язык - это язык программирования с ограниченными выразительными возможностями, ориентированный на некую конкретную предметную область Мартин Фаулер
  • 5. [ DSL ] Зачем? бк и... ско эти уж Ох
  • 6. [ DSL ] BankAccount.configure do |account| account.number 1234 account.type :checking Зачем? Ruby: account.openDate '11.04.1974' account.balance 25382.20 account.holder do |holder| holder.lastName 'Singh' holder.firstName 'Darshan' end end BankAccount: number: 1234 type: checking open_date: '11.04.1974' YAML: balance: 25382.20 account_holder: last_name: Singh first_name: Darshan
  • 7. [ Ключевые моменты ] Где и кто использует DSL?
  • 8. [ Ключевые моменты ] Где и кто использует DSL: - конфигурации # TravisCI config file (.yaml) script: "bundle exec rake travis" before_script: ./bin/ci/before_build.sh services: mongodb rvm: - 1.9.3 notifications: email: - didier@nocoffee.fr - mario@mariovisic.com irc: "irc.freenode.org#locomotivecms" branches: only: - master
  • 9. [ Ключевые моменты ] Где и кто использует DSL: - конфигурации - зависимости пакетов # Gemfile source 'http://rubygems.org' gem 'rails', '3.2.12' group :assets do gem 'therubyracer' gem 'select2-rails', github: "argerim/select2-rails" end group :test do gem "minitest" gem 'mocha', require: false end
  • 10. [ Ключевые моменты ] Где и кто использует DSL: - конфигурации - зависимости пакетов - части фреймворков # Sample resource route resources :products do resources :comments resources :sales do get 'recent', on: :collection end end
  • 11. [ Ключевые моменты ] Где и кто использует DSL: - конфигурации - зависимости пакетов - части фреймворков - системы тестирования # Rspec example describe Account do it "has a balance of zero when first created" do Account.new.balance.should eq(Money.new(0)) expect { @a = 5 }.to change { @a }.from(nil).to(5) end end
  • 12. [ Ключевые моменты ] Где и кто использует DSL: - системы тестирования # language: ru Функционал: Сложение чисел Чтобы не складывать в уме Все, у кого с этим туго Хотят автоматическое сложение целых чисел Сценарий: Сложение двух целых чисел Допустим я ввожу число 50 И затем ввожу число 70 Если я нажимаю "+" То результатом должно быть число 120
  • 13. [ Ключевые моменты ] Где и кто использует DSL: - и еще-еще-еще...
  • 14. [ Ключевые моменты ] Язык программирования
  • 15. [ Ключевые моменты ] Язык программирования Декларативный подход ЧТО делать вместо КАК делать
  • 16. [ Ключевые моменты ] Язык программирования Декларативный подход Природа языка
  • 17. [ Ключевые моменты ] Язык программирования Декларативный подход Природа языка Ограниченные выразительные возможности
  • 18. [ Ключевые моменты ] Язык программирования Декларативный подход Природа языка Ограниченные выразительные Возможности Ориентированность на предметную область
  • 19. [ Категории DSL ] { Внутренний DSL: 'Lisp, Ruby, etc...', }
  • 20. [ Категории DSL ] { Внутренний DSL: 'Lisp, Ruby, etc...', Внешний DSL: 'XML, RegExp, SQL, CSS' }
  • 21. [ Категории DSL ] { Внутренний DSL: 'Lisp, Ruby, etc...', Внешний DSL: 'XML, RegExp, SQL, CSS', Языковые инструментальные средства: '*' }
  • 24. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) Применение обычного API: processor = Processor.new(arch: :i386, cores: 2) dsk1 = Disk.new(size: 150.GB, speed:7200) dsk2 = Disk.new(size: 70.GB, speed:7200) computer = Computer.new({ processor: processor, disks: [dsk1, dsk2] })
  • 25. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) Применение обычного API: ту processor = Processor.new(arch: :i386, cores: 2) рограммис dsk1 = Disk.new(size: 150.GB, speed:7200) ти... ас ятно п етной обл ...пон пр дм dsk2 = Disk.new(size: 70.GB, еspeed:7200) исту ециал computer = Computer.new({ processor:тно сп оня processor, неп[dsk1, dsk2] disks: })
  • 26. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) Связывание методов: computer() .processor() .cores(2) .x64() .disk() .size(150) .speed(7200) .disk() .size(70) .speed(7200)
  • 27. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) Связывание методов: $("#menu") .fadeIn('fast') .addClass("active") .css('marginRight', '10px');
  • 28. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) Связывание методов: $("#menu") .fadeIn('fast') .addClass("active") .css('marginRight', '10px'); $("#thumbnails li").mouseenter(function(e){ $(this).find('img') .stop() .animate({opacity: 0.8}, 300) .end() .find('.viewcasestudy') .fadeIn('fast'); }).fadeIn('fast');
  • 29. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) Связывание методов Последовательность функций: computer() --processor() ----cores(2) ----x64() --disk() ----size(150) ----speed(7200) --disk() ----size(70) ----speed(7200)
  • 30. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) Связывание методов Последовательность функций Вложенные функции: computer( --processor( ----cores(2), ----x64() ––), --disk( ----size(150), ----speed(7200) ––), --disk( ----size(70), ----speed(7200) --) )
  • 31. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) Связывание методов Последовательность функций Вложенные функции Замыкания: ComputerBuilder.build do |c| c.processor do |p| p.cores 2 p.x64 p.speed 2.2 end c.disk do |d| d.size 120 end c.disk do |d| d.size 70 d.speed 7200 d.sata end end
  • 32. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) > Работа с синтаксическим деревом
  • 33. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) > Работа с синтаксическим деревом > Аннотации
  • 34. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) > Работа с синтаксическим деревом > Аннотации > Макросы
  • 35. [ Внутренний DSL ] > Текучий интерфейс (fluent interface) > Работа с синтаксическим деревом > Аннотации def method_missing(m, *args, &block) > Макросы puts "There's no method called #{m} here." end > Динамический отклик
  • 36. [ Внешний DSL ] > Синтаксический анализ
  • 37. [ Внешний DSL ] > Синтаксический анализ Входной поток — это обычный текст (...обычно o_0)
  • 38. [ Внешний DSL ] > Синтаксический анализ Управляемая разделителями трансляция Delimiter-Directed Translation event door_opened event link_clicked event window_closed command play_music command volume_up 10 command send_message "Hello, world"
  • 39. [ Внешний DSL ] > Синтаксический анализ Управляемая разделителями трансляция Delimiter-Directed Translation разделитель event door_openedn event link_clicked event window_closed command play_music command volume_up 10 command send_message "Hello, world" инструкция
  • 40. [ Внешний DSL ] > Синтаксический анализ Управляемая разделителями трансляция Delimiter-Directed Translation Ограничение: event door_opened event link_clicked event window_closed Нет способов обработки иерархического контекста command play_music command volume_up 10 command send_message "Hello, world"
  • 41. [ Внешний DSL ] > Синтаксический анализ Синтаксически управляемая трансляция Syntax-Directed Translation commands event block door_opened link_clicked end command commandDec commandDec end command play_music volume_up 10 play_music volume_up 10 send_message "Hello, world" end
  • 42. [ Внешний DSL ] > Синтаксический анализ Грамматика входного языка. list : eventList commandList ; eventList : 'events' eventDec* 'end'; eventDec : identifier ; commandList : 'commands' commandDec* 'end'; commandDec : identifier identifier? ;
  • 43. [ Внешний DSL ] > Синтаксический анализ Грамматика входного языка. Форма Бэкуса-Наура [E]BNF list : eventList commandList ; eventList : 'events' eventDec* 'end'; eventDec : identifier ; commandList : 'commands' commandDec* 'end'; commandDec : identifier identifier? ;
  • 44. [ Внешний DSL ] > Синтаксический анализ Синтаксический анализатор на основе рекурсивного спуска Recursive Descent Parser
  • 45. [ Внешний DSL ] > Синтаксический анализ Комбинатор синтаксических анализаторов Parser Combinator Комбинатор команд Анализатор Анализатор начала блока команд конца блока команд Комбинатор списка команд Анализатор Анализатор команды аргумента команды
  • 46. [ Внешний DSL ] > Синтаксический анализ Генератор синтаксических анализаторов Parser Generator Генерация Грамматика Синтаксический a : ID INT ; анализатор ID : 'a'..'z'+ ; INT : '0'..'9'+;
  • 47. [ Для чего все это? ] В результате мы должны иметь построенную семантическую модель
  • 48. [ Для чего все это? ] В результате мы должны иметь построенную семантическую модель > Для использования в программном продукте
  • 49. [ Для чего все это? ] В результате мы должны иметь построенную семантическую модель > Для использования в программном продукте > Для генерации нового кода
  • 50. [ Генерация кода ] > Генерация c помощью преобразователя Transformer Generation
  • 51. [ Генерация кода ] > Генерация c помощью преобразователя Transformer Generation > Шаблонная генерация Templated Generation
  • 52. [ Генерация кода ] > Генерация c помощью преобразователя Transformer Generation > Шаблонная генерация Templated Generation > Встроенный помощник Embedment Helper
  • 53. [ Если Вы заинтересованы ] http://martinfowler.com/dslCatalog/
  • 54. [ Спасибо за внимание! ] Кириллов Александр http://twitter.com/saratovsource