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

Санкт-Петербург, весна 2020

Описание

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

Родственные курсы:

  1. Семантика языков программирования (https://compscicenter.ru/courses/programming-language-semantics/2020-spring/)
  2. Основы формальной верификации (https://my.compscicenter.ru/courses/formal-verification/2020-spring/)

Программа курса

1) Из истории вопроса. Программирующие программы.

2) Языки программирования и машинные архитектуры. Что происходит с программой при трансляции. Понятие среды трансляции (toolchain). Раскрутка компилятора (bootstrapping).

3) Как устроен компилятор. Промежуточное представление и просмотры. Программа и библиотека поддержки времени исполнения. Компилятор GCC, инфраструктура LLVM.

4) Канонический интерпретатор. Операционная семантика как способ описания канонического интерпретатора. Простейший язык: выражения и присваивания.

5) Стадия синтаксического анализа - мифы и реальность. Построение атрибутированного дерева. Встраиваимые языки (embedded languages). Поверхностное (shallow) и глубокое (deep) встраивание.

6) Стековая машина. Система команд, операционная семантика. Интерпретатор стековой машины.

7) Компилятор языка выражений в стековую машину. Корректность/частичная корректность компилятора, её обоснование.

8) Символический интерпретатор стековой машины как генератор кода.

9) Система команд x86. Память, регистры, режимы адресации. Среда трансляции GCC, устройство ассемблерного файла, метки и директивы.

10) Генератор кода для выражений и присваиваний. Тестирование.

11) Конструкции управления как операторы.

12) Конструкции управления как выражения. Указатели как значения --- за и против.

13) Процедуры и функции. Варианты организации вызовов и передачи параметров.

14) Массивы и строки. Варианты определения и реализации.

15) Символические выражения и сопоставление с образцом.

16) Функции как значения.

17) Функции высших порядков, дефункционализация, лямбда-лифтинг, построение замыканий.

18) Арифменика с коррекцией (fixnum), автоматическое управление памятью, сборка мусора.

Полезные ссылки и литература

https://github.com/JetBrains-Research/Lama - репозиторий языка Lama;

ocaml.org - среда программирования OCaml;

gcc.gnu.org - компилятор GCC;

llvm.org - инфраструктура LLVM;

gcc.gnu.org/wiki/ListOfCompilerBooks - список книжек про конструирование компиляторов.

N.Wirth. Compiler Construction. Книжка Вирта, одна из немногих, пользуясь которой можно действительно написать компилятор, не умея этого делать предварительно. Идеологически близка курсу, но использует другие технические подходы.

F.Nielson, H-R.Nielson. Semantics with Applications. A formal introduction. Аккуратное введение в семантику языков программирования.

D.Knuth. Semantics of context-free languages. Статья Кнута, в которой вводятся атрибутные грамматики.

G.Hutton, E.Meijer. Monadic parser combinators. Считается первой статьей по данному вопросу.

http://www.felixcloutier.com/x86 - описание системы команд x86.

Некоторые предварительные требования Основы архитектуры и принципы функционирования ЭВМ, основы программирования на ассемблере.

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

Преподаватели

Список лекций

Введение; язык выражений и его операционная семантика

Введение. Предмет и структура курса. Как устроены компиляторы. Разные уровни понимания семантики языков программирования. Формальная семантика. Эталонный интерпретатор. Язык выражений, операционная семантика большого шага.

Линейные программы и стековая машина

Язык линейных программ. Операторы, конфигурации, семантика большого шага. Стековая машина: система команд, семантика большого шага. Компилятор линейных программ для стековой машины.

Архитектура x86-32 с точки зрения компилятора; символический интерпретатор стековых программ

Архитектура и система команд процессора x86-32. Использование системы gcc при программировании на ассемблере. Структура ассемблерной программы с точки зрения компилятора. Символический интерпретатор стековых программ как генератор кода.

Синтаксический анализ

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

Конструкции управления в интерпретаторе

Конструкции ветвления и цикла, операционная семантика большого шага. Синтаксические расширения, вопросы применимости.

Реализация конструкций управления на уровне стековой машины и машинного кода

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

Конструкции управления на уровне выражений

Объединение синтаксических категорий выражений и операторов. Well-formed абстрактный синтаксис, вывод well-formed AST по сокращенному AST, полученному синтаксическим анализатором. Операционная семантика выражений с побочными эффектами. Модификация стековой машины, операционная семантика. Нарушение инварианта символического интерпретатора стековой машины и его восстановление. Генерация машинного кода.

Функции и области описаний в интерпретаторе

Конструкции описания переменный и функций. Well-formedness, вывод значений по умолчанию. Статическое и динамическое связывание свободных переменных. Операционная семантика статического связывания.

Функции и области описания в стековой машине и машинном коде

Расширение стековой машины. Компилятор в стековую машину как интерпретатор с символическим состоянием. Соглашения о вызовах. Локальная стстиам, рамка стека, доступ к локальным аргументам и параметрам, возврат результата функции.

Массивы и встроенные функции.

Массивы. Well-formedness выражений с массивами. Абстракция памяти. Устройство массивов в библиотеке поддержки времени исполнения. Встроенные функции.