Руководство для программистов.Предметно-ориентированные языки программирования

Мартин Фаулер «Предметно-ориентированные языки программирования» Вильямс, 2011 год, 576 стр. (10,1 мб. pdf)

Предметно-ориентированные языки (Domain-Specific Languages — DSL) популярны по нескольким причинам, автор книги расскажет о двух из них: повышение производительности труда разработчиков и улучшение связи с экспертами в предметной области. Правильно выбранный язык может сделать сложный блок кода существенно проще для понимания, что повышает производительность и эффективность работающих с ним.

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

Возможность общения со специалистами на одном языке — это разрушение барьеров общения между программистами и их клиентами, что устраняет массу непониманий в разработке специализированного программного обеспечения. Не бойтесь объема этой книги, так как она в действительности состоит из двух книг объединенных одной обложкой: повествовательная и справочная.

Первую можно читать по основной теме, вторая же это справочник которым следует пользоваться по мере необходимости. Основная целевая аудитория этой книги — профессиональные разработчики ПО, занимающиеся построением предметно-ориентированного языка, имеющие по крайней мере пару лет опыта программирования и хорошо знакомые с основами проектирования программного обеспечения.
ISBN 978-5-8459-1738-6 (рус.)

Оглавление книги

Часть I. Описание 27
Глава 1. Вводный пример 29
1.1. Готическая безопасность 29
1.1.1. Контроллер мисс Грант 30
1.2. Модель конечного автомата 31
1.3. Программирование контроллера мисс Грант 34
1.4. Языки и семантическая модель 41
1.5. Использование генерации кода 43
1.6. Использование языковых инструментальных средств 46
1.7. Визуализация 48

Глава 2. Использование предметно-ориентированных языков 49
2.1. Определение предметно-ориентированных языков 49
2.1.1. Границы DSL 51
2.1.2. Фрагментарные и автономные DSL 53
2.2. Зачем используется DSL 54
2.2.1. Повышение производительности разработки 54
2.2.2. Общение с экспертами в предметной области 55
2.2.3. Изменения в контексте выполнения 56
2.2.4. Альтернативные вычислительные модели 57
2.3. Проблемы с DSL 57
2.3.1. Языковая какофония 58
2.3.2. Стоимость построения 58
2.3.3. Язык гетто 59
2.3.4. Ограниченная абстракция 59
2.4. Более широкая обработка языка 60
2.5. Жизненный цикл DSL 60
2.6. Что такое хороший дизайн DSL 62

Глава 3. Реализация предметно-ориентированных языков 63
3.1. Архитектура обработки DSL 63
3.2. Работа синтаксического анализатора 67
3.3. Грамматики, синтаксис и семантики 68
3.4. Анализ данных 69
3.5. Макросы 72
3.6. Тестирование DSL 72
3.6.1. Тестирование семантической модели 73
3.6.2. Тестирование синтаксического анализатора 76
3.6.3. Тестирование сценариев 80
3.7. Обработка ошибок 80
3.8. Миграция DSL 82

Глава 4. Реализация внутреннего DSL 85
4.1. Свободные API и API командных запросов 85
4.2. Необходимость в слое синтаксического анализа 88
4.3. Использование функций 89
4.4. Коллекции литералов 93
4.5. Использование грамматик для выбора внутренних элементов 95
4.6. Замыкания 96
4.7. Работа с синтаксическим деревом 98
4.8. Аннотации 100
4.9. Расширение литералов 101
4.10. Снижение синтаксического шума 101
4.11. Динамический отклик 102
4.12. Проверка типов 103

Глава 5. Реализация внешнего DSL 105
5.1. Стратегия синтаксического анализа 105
5.2. Стратегия получения вывода 108
5.3. Концепции синтаксического анализа 110
5.3.1. Лексический анализ 110
5.3.2. Грамматики и языки 111
5.3.3. Регулярные, контекстно-свободные и контекстно-зависимые грамматики 112
5.3.4. Нисходящий и восходящий синтаксический анализ 114
5.4. Смешивание с другим языком 115
5.5. XML DSL 117

Глава 6. Выбор между внутренними и внешними DSL 119
6.1. Обучение 119
6.2. Стоимость построения 120
6.3. Осведомленность программистов 121
6.4. Общение с экспертами предметной области 121
6.5. Смешивание в базовом языке 121
6.6. Границы строгой выразительности 122
6.7. Настройка времени выполнения 123
6.8. Скатывание в обобщенность 123
6.9. Соединение DSL 124
6.10. Подведение итогов 124

Глава 7. Альтернативные вычислительные модели 127
7.1. Несколько альтернативных моделей 130
7.1.1. Таблицы решений 130
7.1.2. Система правил вывода 130
7.1.3. Конечный автомат 132
7.1.4. Сеть зависимостей 132
7.1.5. Выбор модели 133

Глава 8. Генерация кода 135
8.1. Выбор объекта генерации 136
8.2. Как генерировать код 138
8.3. Смешивание сгенерированного и рукописного кодов 139
8.4. Генерация удобочитаемого кода 140
8.5. Предварительный анализ генерации кода 141
8.6. Источники дополнительной информации 141

Глава 9. Языковые инструментальные средства 143
9.1. Элементы языковых инструментальных средств 143
9.2. Языки определения схем и метамодели 144
9.3. Редактирование исходного текста и проекционное редактирование 149
9.3.1. Множественные представления 151
9.4. Иллюстративное программирование 151
9.5. Тур по инструментам 153
9.6. Языковые инструментальные средства и CASE-инструменты 154
9.7. Следует ли использовать языковые инструментальные средства 155
Предметно-ориентированные языки программирования

Часть II. Общие вопросы 157

Глава 10. Зоопарк DSL 159
10.1. Graphviz 159
10.2. JMock 160
10.3. CSS 162
10.4. Hibernate Query Language (HQL ) 163
10.5. XAML 164
10.6. FIT 166
10.7. Make и другие 167

Глава 11. Семантическая модель 171
11.1. Как это работает 171
11.2. Когда это использовать 173
11.3. Вводный пример (Java ) 174

Глава 12. Таблица символов 177
12.1. Как это работает 177
12.1.1. Статически типизированные символы 179
12.2. Когда это использовать 180
12.3. Дополнительная литература 180
12.4. Сеть зависимостей во внешнем DSL (Java и ANTLR ) 180
12.5. Использование символьных ключей во внутреннем DSL (Ruby ) 182
12.6. Использование перечислений для статически типизированных символов (Java ) 183

Глава 13. Переменная контекста 187
13.1. Как это работает 187
13.2. Когда это использовать 188
13.3. Чтение INI-файла (C#) 188

Глава 14. Построитель конструкции 191
14.1. Как это работает 191
14.2. Когда это использовать 192
14.3. Построение простых полетных данных (C#) 192

Глава 15. Макрос 195
15.1. Как это работает 195
15.1.1. Текстовые макросы 196
15.1.2. Синтаксические макросы 199
15.2. Когда это использовать 202

Глава 16. Уведомление 205
16.1. Как это работает 205
16.2. Когда это использовать 206
16.3. Очень простое уведомление (C#) 206
16.4. Уведомление анализа (Java ) 207

Часть III. Вопросы создания внешних DSL 211

Глава 17. Трансляция, управляемая разделителями 213
17.1. Как это работает 213
17.2. Когда это использовать 216
17.3. Карты постоянных клиентов (C#) 216
17.3.1. Семантическая модель 217
17.3.2. Синтаксический анализатор 219
17.4. Синтаксический анализ неавтономных инструкций контроллера мисс Грант (Java ) 221

Глава 18. Синтаксически управляемая трансляция 229
18.1. Как это работает 230
18.1.1. Лексический анализатор 231
18.1.2. Синтаксический анализатор 233
18.1.3. Генерация вывода 235
18.1.4. Семантические предикаты 236
18.2. Когда это использовать 236
18.3. Дополнительная литература 236

Глава 19. Форма Бэкуса-Наура 237
19.1. Как это работает 237
19.1.1. Символы множественности (операторы Клини) 239
19.1.2. Другие полезные операторы 240
19.1.3. Грамматики, разбирающие выражения 240
19.1.4. Преобразование РБНФ в БНФ 241
19.1.5. Действия 243
19.2. Когда это использовать 245

Глава 20. Лексический анализатор на основе таблицы регулярных выражений 247
20.1. Как это работает 248
20.2. Когда это использовать 249
20.3. Лексический анализатор контроллера мисс Грант (Java) 249

Глава 21. Синтаксический анализатор на основе рекурсивного спуска 253
21.1. Как это работает 254
21.2. Когда это использовать 257
21.3. Дополнительная литература 257
21.4. Рекурсивный спуск и контроллер мисс Грант (Java ) 257

Глава 22. Комбинатор синтаксических анализаторов 263
22.1. Как это работает 264
22.1.1. Выполнение действий 267
22.1.2. Функциональный стиль комбинаторов 268
22.2. Когда это использовать 268
22.3. Комбинаторы синтаксических анализаторов и контроллер мисс Грант (Java ) 269

Глава 23. Генератор синтаксических анализаторов 277
23.1. Как это работает 277
23.1.1. Встроенные действия 278
23.2. Когда это использовать 280
23.3. Hello World (Java и ANTLR ) 280
23.3.1. Написание базовой грамматики 281
23.3.2. Построение синтаксического анализатора 282
23.3.3. Добавление кода действий в грамматику 284
23.3.4. Применение шаблона Generation Gap 286

Глава 24. Построение дерева 289
24.1. Как это работает 289
24.2. Когда это использовать 291
24.3. Использование синтаксиса построения дерева ANTLR (Java и ANTLR ) 292
24.3.1. Токенизация 293
24.3.2. Синтаксический анализ 294
24.3.3. Наполнение семантической модели 296
24.4. Построение дерева с использованием кода действий (Java и ANTLR ) 299

Глава 25. Встроенная трансляция 305
25.1. Как это работает 305
25.2. Когда это использовать 306
25.3. Контроллер мисс Грант (Java и ANTLR) 306

Глава 26. Встроенная интерпретация 311
26.1. Как это работает 311
26.2. Когда это использовать 311
26.3. Калькулятор (ANTLR и Java ) 312

Глава 27. Внешний код 315
27.1. Как это работает 315
27.2. Когда это использовать 317
27.3. Встраивание динамического кода (ANTLR, Java и Javascript) 317
27.3.1. Семантическая модель 318
27.3.2. Синтаксический анализатор 320

Глава 28. Альтернативная токенизация 325
28.1. Как это работает 325
28.1.1. Кавычки 326
28.1.2. Лексическое состояние 328
28.1.3. Изменение типа токена 330
28.1.4. Игнорирование типов токенов 331
28.2. Когда это использовать 332

Глава 29. Вложенные операторные выражения 333
29.1. Как это работает 333
29.1.1. Применение восходящих синтаксических анализаторов 334
29.1.2. Нисходящие синтаксические анализаторы 335
29.2. Когда это использовать 337

Глава 30. Символ новой строки в качестве разделителя 339
30.1. Как это работает 339
30.2. Когда это использовать 341

Глава 31. Прочие вопросы 343
31.1. Синтаксические отступы 343
31.2. Модулярная грамматика 345

Часть IV. Вопросы создания внутренних DSL 347

Глава 32. Построитель выражений 349
32.1. Как это работает 350
32.2. Когда это использовать 350
32.3. Свободный календарь с построителем и без него (Java ) 351
32.4. Использование для календаря нескольких построителей (Java ) 353

Глава 33. Последовательность функций 357
33.1. Как это работает 357
33.2. Когда это использовать 358
33.3. Простая конфигурация компьютера (Java) 358

Глава 34. Вложенные функции 361
34.1. Как это работает 361
34.2. Когда это использовать 363
34.3. Простой пример конфигурации компьютера (Java ) 363
34.4. Обработка различных аргументов с помощью токенов (C#) 365
34.5. Использование токенов подтипов для поддержки интегрированной среды разработки (Java) 366
34.6. Использование инициализаторов объектов (C#) 368
34.7. Повторяющиеся события (C#) 369
34.7.1. Семантическая модель 369
34.7.2. DSL 372

Глава 35. Соединение методов в цепочки 375
35.1. Как это работает 375
35.1.1. Построители или значения 377
35.1.2. Проблема окончания 377
35.1.3. Иерархическая структура 378
35.1.4. Последовательные интерфейсы 378
35.2. Когда это использовать 379
35.3. Простой пример конфигурации компьютера (Java ) 379
35.4. Соединение методов в цепочки со свойствами (C#) 383
35.5. Последовательные интерфейсы (C#) 383

Глава 36. Перенос области видимости в объект 387
36.1. Как это работает 388
36.2. Когда это использовать 388
36.3. Коды безопасности (C#) 389
36.3.1. Семантическая модель 389
36.3.2. DSL 391
36.4. Использование вычисления экземпляра (Ruby ) 393
36.5. Использование инициализатора экземпляра (Java ) 395

Глава 37. Замыкание 397
37.1. Как это работает 397
37.2. Когда это использовать 401

Глава 38. Вложенные замыкания 403
38.1. Как это работает 403
38.2. Когда это использовать 405
38.3. Заворачивание последовательности функций во вложенное замыкание (Ruby) 405
38.4. Простой пример (C#) 407
38.5. Применение соединения методов в цепочки (Ruby ) 408
38.6. Последовательность функций с явными аргументами замыканий (Ruby) 410
38.7. Применение вычисления экземпляра (Ruby ) 411

Глава 39. Список литералов 415
39.1. Как это работает 415
39.2. Когда это использовать 415
Предметно-ориентированные языки программирования

Глава 40. Ассоциативные массивы литералов 417
40.1. Как это работает 417
40.2. Когда это использовать 418
14 Содержание
40.3. Настройка конфигурации компьютера с помощью списков
и отображений (Ruby ) 418
40.4. Имитация Lisp (Ruby ) 419

Глава 41. Динамический отклик 423
41.1. Как это работает 424
41.2. Когда это использовать 424
41.3. Расчет бонусов с помощью анализа имен методов (Ruby ) 426
41.3.1. Модель 426
41.3.2. Построитель 428
41.4. Расчет бонусов с помощью цепочек вызовов (Ruby ) 429
41.4.1. Модель 430
41.4.2. Построитель 430
41.5. Уменьшение шума в коде контроллера тайника (JRuby ) 433

Глава 42. Аннотации 439
42.1. Как это работает 440
42.1.1. Определение аннотации 440
42.1.2. Обработка аннотаций 441
42.2. Когда это использовать 442
42.3. Пользовательский синтаксис с обработкой времени выполнения (Java ) 443
42.4. Использование метода класса (Ruby ) 445
42.5. Динамическая генерация кода (Ruby ) 446

Глава 43. Работа с синтаксическим деревом 449
43.1. Как это работает 449
43.2. Когда это использовать 450
43.3. Генерация запросов IMAP из условий C# (C#) 451
43.3.1. Семантическая модель 452
43.3.2. Построение из исходного текста C# 454
43.3.3. Отступление 458

Глава 44. Класс таблицы символов 461
44.1. Как это работает 462
44.2. Когда это использовать 462
44.3. Статически типизированный класс таблицы символов (Java ) 463

Глава 45. Шлифовка текста 469
45.1. Как это работает 469
45.2. Когда это использовать 470
45.3. Шлифовка правил дисконта (Ruby ) 470
Глава 46. Расширение литералов 473
46.1. Как это работает 473
46.2. Когда это использовать 474
46.3. Ингредиенты рецепта (C#) 474

Часть V. Альтернативные вычислительные модели 477

Глава 47. Адаптивная модель 479
47.1. Как это работает 480
47.1.1. Внедрение императивного кода в адаптивную модель 481
47.1.2. Инструментарий 483
47.2. Когда это использовать 483

Глава 48. Таблицы принятия решений 485
48.1. Как это работает 485
48.2. Когда это использовать 487
48.3. Вычисление оплаты заказа (C#) 487
48.3.1. Модель 487
48.3.2. Синтаксический анализатор 491

Глава 49. Сеть зависимостей 495
49.1. Как это работает 496
49.2. Когда это использовать 498
49.3. Анализ зелий (C#) 498
49.3.1. Семантическая модель 499
49.3.2. Синтаксический анализатор 500

Глава 50. Система правил вывода 503
50.1. Как это работает 504
50.1.1. Цепочки выводов 505
50.1.2. Противоречивые выводы 505
50.1.3. Шаблоны в структуре правила 506
50.2. Когда это использовать 507
50.3. Проверка для членства в клубе (C#) 507
50.3.1. Модель 507
50.3.2. Синтаксический анализатор 508
50.3.3. Развитие DSL 509
50.4. Правила избрания: расширение членства в клубе (C#) 511
50.4.1. Модель 512
50.4.2. Синтаксический анализатор 514

Глава 51. Конечный автомат 517
51.1. Как это работает 517
51.2. Когда это использовать 519
51.3. Контроллер тайника (Java) 519

Часть VI. Генерация кода 521

Глава 52. Генерация с помощью преобразователя 523
52.1. Как это работает 523
52.2. Когда это использовать 524
52.3. Контроллер тайника (Java генерирует C) 525

Глава 53. Шаблонная генерация 529
53.1. Как это работает 529
53.2. Когда это использовать 531
53.3. Генерация конечного автомата тайника с помощью вложенных условных конструкций (Velocity и Java, генерирующие C) 531

Глава 54. Встроенный помощник 537
54.1. Как это работает 538
54.2. Когда это использовать 538
54.3. Состояния тайника (Java и ANTLR) 539
54.4. Должен ли помощник генерировать HTML (Java и Velocity) 541

Глава 55. Генерация, осведомленная о модели 545
55.1. Как это работает 546
55.2. Когда это использовать 546
55.3. Конечный автомат тайника (C) 546
55.4. Динамическая загрузка конечного автомата (C) 553

Глава 56. Генерация, игнорирующая модель 557
56.1. Как это работает 557
56.2. Когда это использовать 558
56.3. Конечный автомат тайника как вложенные условные конструкции (C) 558

Глава 57. Отделение генерируемого кода с помощью наследования 561
57.1. Как это работает 562
57.2. Когда это использовать 563
57.3. Генерация классов из схемы данных (Java и немного Ruby) 563
Список технической литературы литературы 569
Предметно-ориентированные языки программирования
Предметный указатель 570

Скачать техническую литературу бесплатно10,1 мб. pdf

Похожая литература