├── README.md └── docs ├── analysis.md ├── beginners.md ├── codegen.md ├── courses.md ├── courses_ru.md ├── descent.md ├── dictionary.md ├── general.md ├── general_ru.md ├── metacomp.md ├── parsing.md ├── plt.md ├── runtime.md ├── sea_of_nodes.md ├── spec.md ├── spec_images ├── aiken.jpg ├── async.jpg ├── cooper.jpg ├── custom.jpg ├── fpga.jpg ├── isel.jpg ├── marwedel.jpg ├── modern.jpg ├── par.jpg ├── sbis.jpg ├── ssa.jpg ├── stack.jpg ├── syst.jpg ├── trans.jpg ├── tta.jpg ├── vliw.jpg └── wave.jpg ├── ssa_without_phi.md ├── synthesis.md ├── tutorial.md └── verification.md /README.md: -------------------------------------------------------------------------------- 1 | *Это не очередной awesome-список о компиляторостроении. В будущем мы хотим получить коллективный труд, схожий по форме с известными [Readings in Database Systems](http://www.redbook.io/) и [Teach Yourself Logic 2020a A Study Guide](https://www.academia.edu/41267813/Teach_Yourself_Logic_2020a_A_Study_Guide_midyear_update_). По этой причине pull requests приветствуются в формате, включающем в себя не только ссылку на источник, но и абзац-другой его описания, с указанием желаемого подраздела.* 2 | 3 | # Что читать о разработке компиляторов 4 | 5 | Литература для начинающих 6 | 7 | - [Учебники для начинающих](docs/beginners.md) 8 | - [Рекурсивный спуск в современных компиляторах](docs/descent.md) 9 | - [Кратчайшее введение в создание компилятора (Python)](docs/tutorial.md) 10 | 11 | Учебные курсы 12 | 13 | - [Учебные курсы по конструированию компиляторов](docs/courses.md) 14 | - [Учебные курсы по конструированию компиляторов (на русском языке)](docs/courses_ru.md) 15 | 16 | Общие вопросы компиляции 17 | 18 | - [Литература по общим вопросам компиляции](docs/general.md) 19 | - [Учебники по компиляторам от русскоязычных авторов](docs/general_ru.md) 20 | 21 | Специальные вопросы компиляции 22 | 23 | - [Метавычисления](docs/metacomp.md) 24 | - [Статический и динамический анализ](docs/analysis.md) 25 | - [Порождение целевого кода](docs/codegen.md) 26 | - [Среды выполнения: виртуальные машины, сборка мусора и прочее](docs/runtime.md) 27 | - [Тестирование и формальная верификация компиляторов](docs/verification.md) 28 | - [Теория языков программирования: типы, семантика, интерпретация и прочее](docs/plt.md) 29 | - [Синтез программ и супероптимизация](docs/synthesis.md) 30 | - [ЧаВо по лексическому и синтаксическому разборам](docs/parsing.md) 31 | 32 | Неотсортированное 33 | 34 | - [Sea of Nodes](docs/sea_of_nodes.md) 35 | - [SSA без phi-узлов](docs/ssa_without_phi.md) 36 | - [ChocoPy](https://chocopy.org/) — язык программирования (статически типизированное подмножество Python), набор _учебных курсов_ и _сопроводительных материалов_ для создания (учебных) компиляторов. 37 | - [Англо-русский словарь терминов по вопросам компиляции](docs/dictionary.md) 38 | 39 | **Полезные ссылки** 40 | 41 | 1. Телеграм-канал с новостями и полезными ссылками по тематике разработки языков и компиляторов [PLComp](https://t.me/plcomp). 42 | 1. Телеграм-чат с обсуждением вопросов компиляции [Compiler Development](https://t.me/CompilerDev). 43 | 1. Список компаний, которые занимаются компиляторами [github.com/mgaudet/CompilerJobs](https://github.com/mgaudet/CompilerJobs). 44 | -------------------------------------------------------------------------------- /docs/analysis.md: -------------------------------------------------------------------------------- 1 | # Статический и динамический анализ 2 | 3 | ## Patrick Cousot, Jerome Clarke Hunsaker курс MIT 16.399: Abstract Interpretation (2005 год) 4 | 5 | http://web.mit.edu/afs/athena.mit.edu/course/16/16.399/www/#notes 6 | 7 | _Комментарий от @ksromanov._ 8 | 9 | Курс Кузо — одного из основоположников абстрактной интерпретации, то есть, 10 | обобщения различных точных методов статического анализа, таких как различные 11 | методы статического анализа, основанные на monotone frameworks, статическая 12 | типизация с выводом и без вывода типов, и многих других. 13 | 14 | Курс очень интересен широтой охвата, но страдает хаотичностью изложения. 15 | В частности, непонятно, зачем он включает теорию множеств, втиснутую в 16 | одну лекцию. 17 | 18 | Поэтому лучше начать изучение темы с книг ниже. С другой стороны, 19 | этот курс демонстрирует подход основоположника _Абстрактной интерпретации_, 20 | и не совсем сразу скатывается в страницы формул в отличие от монографии 21 | Кузо _Principles of Abstract Interpretation_. 22 | 23 | ## Static Program Analysis 24 | 25 | _Комментарий от @ksromanov._ 26 | 27 | Курс, разработанный Anders Møller и др. (Aarhus University). 28 | 29 | Конспект лекций: https://cs.au.dk/~amoeller/spa/ 30 | 31 | Обзорная лекция на youtube (часть 1): https://www.youtube.com/watch?v=Lr4cMmaJHrg 32 | 33 | Обзорная лекция на youtube (часть 2): https://www.youtube.com/watch?v=6QQSIIvH-F0 34 | 35 | Многими (в числе которых, скажем, John Regehr) данный специальный курс по вопросам статического анализа считается лучшим в своем роде. Мне имеет смысл только присоединиться к этому мнению. Лекции написаны очень хорошо: легкий язык, современный подход к предмету, большой охват материала. 36 | 37 | Это превосходный курс, в который до сих пор вносятся изменения. В курсе рассказывается 38 | про разновидности статического анализа программ, базирующихся на подходе абстрактной интерпретации: 39 | вывод типов Хиндли-Милнера, Data-flow/Control-flow анализы, базирующиеся на Monotone Frameworks (частный 40 | случай абстрактной интерпретации с явным использованием решёток в качестве абстрактного домена), 41 | техника widening/narrowing. Широта охвата впечатляет. 42 | 43 | ## Xavier Rival, Kwangkeun Yi. Introduction to Static Analysis An Abstract Interpretation Perspective (2020) 44 | 45 | _Комментарий от @ksromanov._ 46 | 47 | Великолепная книга, прекрасно сочетающая системность, строгость, простоту и охват. 48 | Её даже можно было бы назвать «Статический анализ программ для физиков», настолько она легко 49 | читается, не теряя достаточной строгости. Книга, по-сути, является учебником, плавно 50 | переходящим в справочник. 51 | 52 | В первой главе авторы наглядно рассказывают об основных 53 | понятиях и методах абстрактной интерпретации на примере графического языка. В частности 54 | упоминается о тонкостях применимости соответствия Галуа. В последующих главах авторы 55 | работают с простым интерпретируемым языком, раскрывая метод построения статических 56 | анализаторов с помощью подхода абстрактной интерпретации. 57 | 58 | После изложения теории, авторы предлагают чёткий и последовательный алгоритм создания 59 | статического анализатора, после чего демонстрируют учебный анализатор, написанный на OCaml. 60 | Заключительные главы книги уже служат скорее справочником по текущему состоянию поля. 61 | 62 | В отличие от курса Anders'а Møller'а это не самоучитель, а учебник, к которому по-идее, 63 | должен идти задачник. Поэтому она не заменяет курс _SPA_, а дополняет. К сожалению, 64 | я не могу сказать, в каком порядке стоит читать эти книги. Вполне возможно, что 65 | курс _SPA_ должен идти вторым. 66 | 67 | С моей точки зрения, авторы используют слегка нестандартную, но очень наглядную терминологию 68 | _transitional semantics_ (семантика малого шага) и _compositional semantics_ (семантика большого шага), 69 | но они явно проговаривают связь с общеупотребимыми терминами. Разумеется, какие-то темы 70 | изложены явно подробнее в _SPA_, например оператор _widening_ и _narrowing_. 71 | -------------------------------------------------------------------------------- /docs/beginners.md: -------------------------------------------------------------------------------- 1 | # Литература для начинающих 2 | 3 | Здесь вы не найдете знаменитой "книги дракона" и других подобных учебников. На мой взгляд, такие учебники не подходят для самообучения. Для начинающих полезно использовать конструктивный подход: практическое создание компилятора некоторого учебного языка прямо в процессе изучения минимального объема теории. 4 | 5 | ## Никлаус Вирт. Построение компиляторов (2010) 6 | 7 | *Комментарий от @true-grue*. Небольшой (131 страница) учебник по созданию компилятора подмножества языка Оберон для RISC-процессора. Книга содержит необходимый минимум теории, написана ясным языком. Среди недостатков: компилятор предлагается писать на самом Обероне и это оборачивается некоторой тяжеловесностью реализации с упором на низкоуровневое кодирование. На мой взгляд, это один из лучших учебников для начального чтения по тематике компиляторов для императивных языков. 8 | 9 | *Комментарий от @vkazanov*. В этой маленькой книге изложен виртовский подход к разработке компиляторов, в котором отбрасываются любые усложнения вроде оптимизаций или сложностей кодогенерации, и читатель идет к работающему языку самым коротким путем. Теории тут нет, все пояснения делаются на пальцах, формируя интуитивное понимание проблем. Соглашусь с @true-grue в том, что это очень хороший вводный учебник, после которого, в общем-то, уже можно читать код популярных интерпретатируемых языков вроде Python или Emacs Lisp. Несколько портит впечатление только использование старомодного и многословного Оберона, но ничего непреодолимого в этом языке нет. 10 | 11 | ## Н. Вирт. Алгоритмы + структуры данных = программы (1985) 12 | 13 | *Комментарий от @true-grue*. Хорошо известный в советское время учебник Вирта по базовым алгоритмам и структурам данных. Какое он имеет отношение к компиляторам? Последний раздел в книге называется "Структура языков и трансляторы". Там в сжатой форме рассказывается, как построить компилятор для подмножества Паскаля PL/0 с порождением кода для стековой виртуальной машины. Из этого раздела, очевидно, потом и родился отдельный учебник "Построение компиляторов". Раздел занимает всего 70 страниц, и с азами создания компиляторов вполне способен познакомить. Но читать его лучше тем, кто не боится "архаичного" стиля, ведь оригинальное издание книги вышло в далеком 1976 году! Кстати говоря, в более поздних редакциях этого учебника вы уже не найдете раздела по компиляторам. 14 | 15 | ## Essentials of Compilation: An Incremental Approach 16 | 17 | [Скачать](https://jeapostrophe.github.io/courses/2018/spring/406/notes/book.pdf) 18 | 19 | [Исходные тексты на github](https://github.com/IUCompilerCourse/Essentials-of-Compilation) 20 | 21 | *Комментарий от @true-grue*. Современный курс по созданию компилятора для Лисп-подобного языка. К достоинствам подхода авторов относится выбор S-выражений в качестве входного языка. То есть задача лексического и синтаксического анализа не рассматривается. И это имеет свои плюсы, поскольку такой подход позволяет сконцентрироваться на действительно важных вещах (middle-end, back-end). При этом особенно глубоко авторы в дебри реализации функциональных языков не уходят, сведения из курса вполне применимы и для реализации компилятора императивного языка. Изложение ведется с использованием Racket (диалект Лиспа), широко применяется сопоставление с образцом. Помимо прочего изучаются: выбор инструкций, распределение регистров, проверка типов, сборка мусора и так далее. Курс небольшой, всего 119 страниц. Можно рекомендовать всем начинающим компиляторщикам, знакомым с Лиспом. 22 | 23 | Существует версия курса для языка [Python](https://github.com/langjam/langjam/blob/main/resources/Python_compiler.pdf). 24 | 25 | Данный курс и некоторые другие курсы со сходным содержанием были вдохновлены следующей статьей: [A Ghuloum. An Incremental Approach to Compiler Construction](https://github.com/namin/inc/blob/master/docs/paper.pdf?raw=true). Основная мысль статьи в том, что простейший компилятор (для Лисп-подобного языка) вполне по силам начинающему, если работа над компилятором будет вестись инкрементально: на каждом небольшом шаге мы будем иметь пусть и примитивный, но, все-таки, работающий компилятор. Кстати говоря, истоки данного подхода можно проследить в известной серии заметок [J. Crenshaw. Let's Build a Compiler](https://compilers.iecc.com/crenshaw/). Профессиональный отзыв о данном подходе можно прочесть в заметке [My First Fifteen Compilers](https://blog.sigplan.org/2019/07/09/my-first-fifteen-compilers/). 26 | 27 | *Комментарий от @vkazanov*. По совету @true-grue ознакомился с Essentials of Compilation. Думаю, это мой новый фаворит из всех небольших вводных курсов по компиляции. Использование Lisp в качестве промежуточного представления позволяет абстрагироваться от всяких неинтересных вещей вроде синтаксиса/семантики, и шаг за шагом приближать внутреннее представление кода до ассемблера. Думаю, совершенно не важно, что это Lisp, т.к. использование s-выражений только упрощает визуализацию внутренних представлений после каждого из преобразований. 28 | 29 | ## T. Parr. Language Implementation Patterns: Create Your Own Domain-Specific and General Programming Languages 30 | 31 | *Комментарий от @true-grue*. Для многих программистов теория компиляции важна в связи с желанием создавать различные небольшие DSL для своих задач. Здесь может оказать помощь рассматриваемая книга, которую отличает очень большое количество практически полезных примеров. Автор сумел "на пальцах" объяснить полезные методы построения парсеров (включая подход packrat), различные техники обхода AST (включая term rewriting), способы создания стековых и регистровых виртуальных машин, методы source-to-source трансляции. Изложение ведется с использованием инструментария ANTLR (автором которого T. Parr и является) и языка Java. По теме введения в создание собственных little languages и простых генераторов программ данную книгу можно смело советовать, у нее практически нет конкурентов. 32 | 33 | *Комментарий от @vkazanov*. По долгу службы мне чаще приходится иметь дело с небольшими языками запросов, которые конвертируются в запросы на SQL или байт-код специализированных мини-БД. Одна из характерных проблем в данном случае - коротко вводить в курс дела коллег-программистов, не имеющих опыта разработки парсеров или, тем более, бэкэндов компиляторов. Так вот, эта книга - лучшая рекомендация в данном случае. 34 | 35 | ## [Robert Nystrom. Crafting Interpreters](http://craftinginterpreters.com/contents.html) (2020) 36 | 37 | *Комментарий от @true-grue*. В последнее время появляется много литературы, где вопросы построения интерпретаторов и компиляторов разъясняются "простыми словами". Иной раз авторы слишком увлекаются частными вопросами реализации и не дают читателю возможность "за деревьями увидеть лес". В этом плане небольшая книга от Rob Nystrom выделяется в лучшую сторону. Во-первых, ее автор -- практикующий разработчик с большим опытом в области создания игр. Во-вторых, вопросами компиляции он интересуется серьезно. В частности, его старую заметку в блоге на тему реализации парсера Пратта можно считать одной из лучших на эту тему. 38 | 39 | Crafting interpreters -- это небольшое введение в построение компиляторов и интерпретаторов для начинающих. От читателя требуется только знание языка Си и знакомство с языками в духе JavaScript или Python. Подобный динамически-типизированный язык и будет разработан в процессе изучения книги. Главный плюс Crafting Interpreters, на мой взгляд, в том, что ее автор обладает талантом рассказывать просто о сложном. 40 | 41 | ## Douglas Thain. Introduction to Compilers and Language Design, 2nd edition, 2020. (Revision Date: January 15, 2021) 42 | 43 | Доступна в печатном виде и бесплатно в виде PDF: https://www3.nd.edu/~dthain/compilerbook/ 44 | 45 | В книге сжато излагаются все основные аспекты компиляции: лексический анализ, синтаксический анализ, деревья абстрактного синтаксиса и семантический анализ, промежуточные представления, представление данных в памяти, порождение кода, оптимизации. Изложение ведётся на языке C, используются инструменты Flex и Bison. В качестве сквозного примера рассматривается несложный императивный язык программирования. 46 | 47 | ## Mak R. Writing Compilers and Interpreters: A Software Engineering Approach (2009) 48 | 49 | ## Хантер Р. Компиляторы. Краткий справочник (2018) 50 | 51 | *Комментарий от @vkazanov*. Небольшая вводная книга, около 200 страниц, рассказывающая о базовых вопросах компиляции. Упоминаются лексический, синтаксический и семантический анализ, коротко по размещению переменных в памяти и кодогенерации. Темы изложены лаконично, элементы теории удачно перемежаются с простыми примерами (разбор методом рекурсивного спуска, lex, yacc и т.д.). Основная проблема книги - поверхностность и незаконченность, то есть работающего компилятора читатель все же не увидит. С другой стороны, в качестве вводной она вполне сойдет. 52 | 53 | *Комментарий от @true-grue*. На русский язык до сих пор не переведены Аппель с Мучником, но вот Хантера у нас переводят с удовольствием. Есть и советское издание 1984 года, и переводы от «Вильямса» 2002 и 2017 года. Хантер написал несколько книг, но материал, на мой взгляд, в них различается мало — читателя обучают создавать компилятор Паскаля с помощью самых базовых подходов. Я не заметил у автора каких-то интересных педагогических приемов и, в целом, предпочел бы Хантеру Вирта. 54 | -------------------------------------------------------------------------------- /docs/codegen.md: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------------- /docs/courses.md: -------------------------------------------------------------------------------- 1 | # Учебные курсы по конструированию компиляторов 2 | 3 | ## Language Translation And Implementation 4 | Курс, разработанный Ray Toal (Loyola Marymount University). 5 | 6 | Конспект лекций: https://cs.lmu.edu/~ray/classes/cc/ 7 | 8 | Автор курса -- исследователь в области ЯП и компиляторов. Кроме того, он написал небезынтересную книгу Programming Language Explorations. Рассматриваемый курс предназначен для самых начинающих студентов. И как же просто и детально там преподносится материал! И весьма свежий, надо сказать, материал. Кажется, не существует более практико-ориентированного курса, чем этот. Вместе с тем, автор не забывает и о формальной стороне вопроса -- достаточно много усилий потрачено, в том числе, на строгую статическую и динамическую семантику. Удачным считаю выбор современного инструмента Ohm (на основе формализма PEG) для работы с синтаксисом. В качестве основного языка реализации используется JavaScript. Однако в разделе, посвященном генерации кода, автор переходит на SML, демонстрируя положительные стороны использования сопоставления с образцом для соответствующих задач. 9 | 10 | ## Post-Modern Compiler Design 11 | Курс, разработанный Tiark Rompf (Purdue University). 12 | 13 | Конспект лекций: https://www.cs.purdue.edu/homes/rompf/pmca/vol1/ 14 | 15 | Tiark Rompf -- известный специалист в области разработки высокопроизводительных DSL, разработчик системы LMS. Конспект лекций представляет собой краткое введение в построение простого компилятора для начинающих, речь идет о пошаговой реализации подмножества Scala. Язык Scala используется и для написания компилятора, что является очень уместным выбором -- приведенный код частей MiniScala весьма выразительный и читаемый. Автор для разбора синтаксиса использует рекурсивный спуск и разбор по приоритетам для выражений (precedence climbing). AST представлено в виде термов, вместо неуклюжих "посетителей" используется сопоставление с образцом... -- словом, это действительно современный подход к построению компилятора с нуля. Жаль только, что текст лекций обрывочный, не имеет завершенного вида. 16 | 17 | 18 | ## Compiler Construction for Undergraduates и Advanced Compiler Construction 19 | 20 | Курсы, разработанные Keith Cooper (Rice University). 21 | 22 | Слайды: https://www.clear.rice.edu/comp412/Lectures/ (ссылка протухла) 23 | 24 | Слайды: https://www.clear.rice.edu/comp512/Lectures/ 25 | 26 | K. Cooper является одним из крупнейших специалистов в области теории компиляции. Он также и соавтор одного из лучших учебников по вопросам компиляции Engineering a Compiler. В этом смысле и от рассматриваемых учебных курсов стоит ожидать многого. 27 | 28 | Проблема чрезмерной специализации, узкого профессионального кругозора, типична как среди практиков -- разработчиков компиляторов, так и среди соответствующих преподавателей. В этом отношении курсы Кейта Купера, на мой взгляд, отличаются в самую лучшую сторону по систематичности и глубине излагаемого материала. Для обоих курсов доступны только слайды, но они весьма подробные и наглядные. 29 | 30 | Материал курса COMP 412 является расширенной версией учебника Engineering a Compiler. Курс по специальным вопросам компиляции COMP 512 полностью посвящен вопросам оптимизации. Здесь даже для профессионального компиляторщика найдется целый кладезь ценных знаний. Автор много рассказывает об истории компиляции, о развитии соответствующих методов, приводит ссылки на массу исторически важных материалов. 31 | 32 | COMP 412/512 -- одни из немногих существующих университетских курсов, на основе которых у студентов формируется общая, современная, цельная картина положения дел в области компиляторов, требуемая для настоящего профессионала-компиляторщика. 33 | 34 | ## Compiler Construction 35 | Курс, разработанный Eelco Visser (Delft University of Technology). 36 | 37 | Слайды: https://tudelft-cs4200-2019.github.io/lectures/ 38 | 39 | E. Visser известен работами в области создания инструментов для разработки ЯП общего назначения и DSL (Stratego, Spoofax). 40 | Рассматриваемый курс предназначен для начинающих, автор практически не касается вопросов оптимизации. В целом, материал достаточно традиционный. Новизна здесь в том, каким образом автор предлагает писать компиляторы, с помощью каких подходов и инструментов. B этом отношении можно считать, что это курс по компиляторам из будущего. Еще нескоро популярные компиляторы будут иметь настолько простую, ясную и декларативную структуру. 41 | 42 | ## Compiler Construction 43 | Курс, разработанный Sebastian Hack и др. (Universität des Saarlandes). 44 | 45 | Слайды: http://compilers.cs.uni-saarland.de/teaching/cc/2017/ 46 | 47 | S. Hack хорошо известен компиляторщикам-профессионалам по своим работам в области формы SSA. Хотя курс начинается и достаточно традиционно (LL/LR-грамматики и подобное), но основной упор в нем делается на современные методы статического анализа, использования SSA и порождения кода. Имеются уникальные и важные материалы, изложенные на основе собственных разработок S. Hack и его коллег. 48 | 49 | ## Compiler Design 50 | Курс, разработанный Frank Pfenning (Carnegie Mellon University). 51 | 52 | Конспект лекций: https://www.cs.cmu.edu/~fp/courses/15411-f14/schedule.html 53 | 54 | F. Pfening специализируется в области математической логики и теории ЯП. 55 | Конспекты лекций написаны очень простым и ясным языком, хотя и касаются достаточно сложных вопросов (формальная семантика, потоковый анализ и др.). Раздел по SSA заслуживает особого внимания -- насколько же красиво автор разъясняет детали (причем, phi-функции появляются только в завершении лекции)! 56 | 57 | ## Advanced Compilers β 58 | Курс, разработанный Adrian Sampson (Cornell University). 59 | 60 | Блог курса: https://www.cs.cornell.edu/courses/cs6120/2019fa/blog/ 61 | 62 | Современный курс для тех, кого интересуют специальные вопросы компиляции. Скорее даже -- курс для опытных разработчиков, которых интересуют вопросы компиляции для новых вычислительных архитектур. Материалы организованы в виде блога, который можно читать в духе: "что нового в мире оптимизирующих компиляторов". 63 | -------------------------------------------------------------------------------- /docs/courses_ru.md: -------------------------------------------------------------------------------- 1 | # Учебные курсы по конструированию компиляторов (на русском языке) 2 | 3 | ## "Основы методов трансляции" и "Методы оптимизирующей компиляции" 4 | 5 | Курсы от сотрудников заслуженной, но ныне не существующей "компиляторной" компании "Эксельсиор" (НГУ). 6 | 7 | На сайте компании материалы уже недоступны, но до них все еще можно добраться по прямым ссылкам. Есть только тексты рабочих программ и слайды лекций. 8 | 9 | [Программа курса "основы методов трансляции"](https://www.excelsior.ru/files/pages/ProgramCC1_0.pdf) 10 | 11 | - [Лекция 1](https://www.excelsior.ru/files/pages/l1.pdf) 12 | - [Лекция 2](https://www.excelsior.ru/files/pages/l2.pdf) 13 | - [Лекция 3](https://www.excelsior.ru/files/pages/l3.pdf) 14 | - [Лекция 4](https://www.excelsior.ru/files/pages/l4.pdf) 15 | - [Лекция 5](https://www.excelsior.ru/files/pages/l5.pdf) 16 | - [Лекция 6](https://www.excelsior.ru/files/pages/l6.pdf) 17 | - [Лекция 7](https://www.excelsior.ru/files/pages/l7.pdf) 18 | - [Лекция 8](https://www.excelsior.ru/files/pages/l8.pdf) 19 | - [Лекция 9](https://www.excelsior.ru/files/pages/l9.pdf) 20 | 21 | 22 | [Программа курса "Методы оптимизирующей компиляции"](https://www.excelsior.ru/files/pages/programcc2.pdf) 23 | 24 | - [Лекция 1](https://www.excelsior.ru/files/pages/ll1.pdf) 25 | - [Лекция 2](https://www.excelsior.ru/files/pages/ll2.pdf) 26 | - [Лекция 3](https://www.excelsior.ru/files/pages/ll3.pdf) 27 | - [Лекция 4](https://www.excelsior.ru/files/pages/ll4.pdf) 28 | - [Лекция 5](https://www.excelsior.ru/files/pages/ll5.pdf) 29 | - [Лекция 6](https://www.excelsior.ru/files/pages/ll6.pdf) 30 | - [Лекция 7](https://www.excelsior.ru/files/pages/ll7.pdf) 31 | 32 | Особый интерес представляет курс "Методы оптимизирующей компиляции", где освещаются такие вопросы, как статический потоковый анализ и форма SSA (в том числе распределение регистров на уровне формы SSA). 33 | 34 | ## "Языки программирования и методы трансляции" 35 | 36 | Курс С.З. Свердлова (Вологодский государственный университет). 37 | 38 | Доступны видеозаписи лекций на youtube. 39 | 40 | - [Лекция 0. Вводная лекция. Разработка компилятора](https://www.youtube.com/watch?v=gelbeLKYBi8) 41 | - [Лекция 1. Контекстный анализ](https://www.youtube.com/watch?v=jAs-aQlUuZs) 42 | - [Лекция 2. Контекстный анализ. Импорт, присваивание, вызов процедуры. Контекстный анализ выражений. Проверка типов](https://www.youtube.com/watch?v=0N9GkhLv6bI) 43 | - [Лекция 3. Контекстный анализ операторов. Генерация кода](https://www.youtube.com/watch?v=ySvYQlJa468) 44 | - [Лекция 4. Виртуальная машина](https://www.youtube.com/watch?v=HZYO0EOgF2E) 45 | - [Лекция 5. Виртуальная машина. Оптимизация машинного кода](https://www.youtube.com/watch?v=OQQBVEg2KWA) 46 | - [Лекция 6. Генерация кода для выражений](https://www.youtube.com/watch?v=OUHqiQIc2Ho) 47 | - [Лекция 7. Завершаем разработку компилятора](https://www.youtube.com/watch?v=tEpim8mqlJA) 48 | - [Лекция 8. Рефакторинг. Бенчмаркинг. Статический анализ](https://www.youtube.com/watch?v=4JB_hVnjHs8) 49 | - [Лекция 9. Трансляция процедур. Простой ассемблер](https://www.youtube.com/watch?v=Z61DWu3kFms) 50 | - [Лекция 10. Ассемблер. Компилятор компиляторов. Раскрутка](https://www.youtube.com/watch?v=q7pXhvgH7m0) 51 | 52 | Речь идет о разработке компилятора подмножества языка Оберон. Может использоваться в качестве дополнения к одноименному учебнику того же автора. При этом, в отличие от учебника, языком реализации в видеокурсе является Питон. Одна из версий разрабатываемого в рамках видеокурса компилятора доступна здесь: https://github.com/c3c-git/O-Python 53 | 54 | ## "Теория компиляторов" 55 | 56 | Курс В.Э. Карпова (МИЭМ). 57 | 58 | Доступны конспекты лекций, слайды и методические указания. 59 | 60 | http://rema44.ru/resurs/students/karpov/ 61 | 62 | Конспект лекций "Теория компиляторов" из первой части курса имеет достаточно традиционное "драконовское" содержание. Совсем иное дело -- вторая часть курса (см. "методические материалы по выполнению курсовой работы"). Это введение в методы компиляции для машин с параллелизмом уровня команд (VLIW). Автор использует, в том числе, советский опыт в этой области ("ярусно-параллельная форма"). Кроме того, для задач компиляции автором уместно, хотя и в очень скромном объеме, используется язык Пролог. 63 | 64 | ## "Языки программирования и компиляторы" 65 | 66 | Курс Д.Ю. Булычева (СПбГУ, JetBrains Research). 67 | 68 | https://compscicenter.ru/courses/compilers/2018-spring/ 69 | 70 | Доступны видеозаписи лекций на youtube и конспекты. 71 | 72 | Это современный курс с уклоном в формальную семантику и функциональное программирование. Вопросы оптимизации кода, по большому счету, не рассматриваются. В качестве языка реализации компиляторов выбран Ocaml. Изложение ведется в тяжеловесном, сложном для восприятия стиле. В качестве вводного данный курс трудно рекомендовать. 73 | 74 | ## Конспект лекций по специальным вопросам теории формальных языков и синтаксического анализа (в разработке) 75 | 76 | Курс Семёна Григорьева и др. (СПбГУ, JetBrains Research). 77 | 78 | https://github.com/JetBrains-Research/FormalLanguageConstrainedReachability-LectureNotes 79 | 80 | ## "Разработка компиляторов на платформе .NET" 81 | 82 | Курс 2001 года, авторы А.А. Терехов, Н. Вояковская, Д. Булычев, А. Москаль (СПбГУ). 83 | 84 | Доступен конспект лекций. 85 | 86 | Если оставить в стороне информацию по внутренностям платформы .Net, то данный текст представляет собой, в основном, выжимку из книги Дракона, учебников Касьянова и Мучника. Тем не менее, раздел по оптимизации достаточно детален. Кроме того, полезно сверяться с этим конспектом по части русскоязычной терминологии. 87 | -------------------------------------------------------------------------------- /docs/descent.md: -------------------------------------------------------------------------------- 1 | # Рекурсивный спуск в современных компиляторах 2 | 3 | Что такое рекурсивный спуск? Если говорить кратко, это один из вариантов синтаксического разбора сверху вниз. Он основан на ручном переводе в исполняемый код синтаксических правил, представленных, например, в БНФ. В теле каждого правила вхождение нетерминала заменяется вызовом соответствующей функции, а альтернатива моделируется с помощью конструкции ветвления. 4 | 5 | Есть мнение, что времена рекурсивного спуска давно прошли. Существуют мощные программы-генераторы, позволяющие автоматизировать процесс разработки парсеров. Тем не менее, имеется большое число современных, промышленных компиляторов, использующих рекурсивных спуск. Вот лишь несколько примеров: 6 | 7 | * GCC 8 | * Clang 9 | * rustc 10 | * Swift 11 | * Go 12 | * Lua 13 | * TypeScript 14 | * V8 15 | * Roslyn 16 | * Elm 17 | * javac 18 | * Kotlin 19 | 20 | Впечатляющий перечень, не правда ли? В чем же причина такой популярности древнего метода, требующего ручного труда разработчика компилятора? 21 | 22 | Рекурсивный спуск не ограничивается классом граматик LL(1). В коде легко можно реализовать и предпросмотр на произвольное количество токенов, и запоминание промежуточных результатов разбора, и механизм отката. 23 | 24 | Важно отметить, что в чистом виде рекурсивный спуск действительно используется нечасто. Таким образом обычно реализуют компиляторы языка Oberon. В основном же, разработчики компиляторов не в восторге от необходимости иметь дело с разбором выражений с приоритетами. Проблемы с необходимостью факторизации грамматики и с неважным быстродействием разбора выражений с большим числом приоритетов решаются, тем не менее, достаточно просто — с помощью техники, основанной на классическом алгоритме сортировочной станции Дейкстры (shunting yard), которая легко интегрируется в общую схему рекурсивного спуска. Речь о precedence climbing/Pratt parser. В результате разбор выражений легко представить в компактной табличной форме. 25 | 26 | Ниже представлен перечень некоторых положительных качеств рекурсивного спуска в сравнении с генераторами синтаксических анализаторов. 27 | 28 | 1. Простота интеграции с остальным кодом компилятора. Настройка и в целом попытка достичь взаимопонимания с программой-генератором иной раз обходится дороже, чем прямая реализация разбора в коде. 29 | 2. Возможность оптимизации быстродействия и потребления памяти. От кода рекурсивного спуска обычно проще добиться необходимых характеристик, чем от программы-генератора, которая для пользователя выглядит, как черный ящик. 30 | 3. Возможность детальной диагностики ошибок, а также восстановления после ошибок. В ручном режиме проще обработать сложные специальные случаи. Это одна из причин, по которой Rust и Elm, отличающиеся подробными сообщениями об ошибках, используют рекурсивный спуск. 31 | 4. Простота отладки. Свой код отладить проще, чем "выхлоп" программы-генератора. 32 | 5. Мощность разбора. В ручном режиме, теоретически, возможен разбор для неограниченных или, иначе, Тьюринг-полных грамматик. Это необходимо для полной поддержки языков со свободно переопределяемым синтаксисом, таких, как Forth или Lisp (reader macro), а также для [разбора шаблонов в C++](http://replay.waybackmachine.org/20060918135742/http://osl.iu.edu/~tveldhui/papers/2003/turing.pdf). 33 | 6. Простота описания разбора. В случае с программами-генераторами приходится изучать дополнительный и не всегда гибкий формализм описания грамматики языка. При этом читаемость и декларативность формализма зачастую не выдерживают столкновения с реальностью в виде контекстно-зависимых грамматик сложных языков программирования и необходимости совершения дополнительных семантических действий на стадии разбора. 34 | 7. Легкость добавления дополнительных возможностей: инкрементальный разбор, устойчивость к ошибкам в синтаксисе (resilient parsing) и так далее. 35 | 36 | Здесь необходимо отметить, что не все современные генераторы парсеров однозначно уступают рекурсивному разбору с точки зрения перечисленных выше пунктов. Весьма гибкими, к примеру, являются Menhir (Ocaml) и SDF3 (Java), но и в их случае п.1 зачастую оказывается серьезным препятствием на пути к использованию. Вот несколько случаев, когда использование генератора синтаксического анализатора представляется вполне оправданным: 37 | 38 | 1. Прототипирование языка программирования, синтаксис которого еще не до конца сформирован. 39 | 2. Разработка инструмента статического анализа, использующего несколько входных языков с различным синтаксисом. 40 | 3. Подсветка синтаксиса. В этой задаче грамматику входного языка часто можно упростить для удобства ее представления на языке программы-генератора. 41 | 4. Некоторые варианты фаззинг-тестирования. Удобно, когда одно и то же описание грамматики языка используется и для разбора, и для порождения случайных фраз на этом языке. 42 | 43 | Разумеется, рекурсивный спуск неидеален. Особенные проблемы вызывает тот факт, что в коде "за деревьями не видно леса", то есть восстановить грамматику языка по программной реализации бывает очень тяжело. То же касается и сложности внесения изменений в разбор. 44 | Все это является следствием императивного, низкоуровневого подхода к реализации парсера. Можно ли описать разбор кодом, но в декларативно-функциональном духе, в виде eDSL? Можно. В этом случае мы приходим к идее использования комбинаторов синтаксического разбора, но о них лучше поговорить отдельно. 45 | -------------------------------------------------------------------------------- /docs/dictionary.md: -------------------------------------------------------------------------------- 1 | # Англо-русский словарь терминов по вопросам компиляции 2 | 3 | **Abstract syntax tree (AST)** — поскольку речь идет об абстрактном синтаксисе, представленном в виде дерева, то корректнее говорить о **дереве абстрактного синтаксиса**. В настоящий момент наиболее широко используется не слишком удачный термин **абстрактное синтаксическое дерево (АСД)** [1, 2]. Термин **дерево разбора** [5] может подразумевать и работу с конкретным синтаксисом. Также существует оригинальный, но забытый термин **дерево Канторовича** [1]. 4 | 5 | **Back end** — **фаза генерации** [5], **фаза синтеза**, **задний план**. 6 | 7 | **Basic block** — **линейный участок** [1]. Также встречаются определения **базовый блок** и **базисный блок** [1]. 8 | 9 | **Big/small-step operational semantics** — **операционная семантика большого/малого шага** [7] или **операционная семантика с большим/малым шагом** [8]. 10 | 11 | **Constant folding** — **свертка констант** [5]. 12 | 13 | **Constant propagation** — **распространение констант**, **продвижение констант**, **втягивание констант** [5]. 14 | 15 | **Common subexpression elimination (CSE)** — **экономия выражений** [3], в дословном распространенном переводе **удаление общих подвыражений**. 16 | 17 | **Compiler** — **компилятор**, **транслятор** [6]. 18 | 19 | **Compiler generator (compiler-compiler, compiler framework)** — **система построения трансляторов (СПТ)** [5]. 20 | 21 | **Control-flow graph (CFG)** — **управляющий граф** [1], **граф потока управления**, **граф переходов** [1], **уграф** [1], **схема Мартынюка** [1]. 22 | 23 | **Coroutine** — **сопрограмма**. 24 | 25 | **Denotational semantics** — **денотационная семантика** [8]. 26 | 27 | **Domain-specific language (DSL)** — **проблемно-ориентированный язык (ПОЯ)** или **предметно-ориентированный язык**. 28 | 29 | **Dead code elimination (DCE)** — **удаление мертвого кода**, **чистка программы** [5]. 30 | 31 | **Front end** — **фаза декомпозиции** [5], **фаза анализа**, **передний план**. 32 | 33 | (Function) **Inlining** — **подстановка функции**, **встраивание функции**, **распроцедурирование** [5]. 34 | 35 | **Instruction scheduling** — **планирование инструкций (команд)**. 36 | 37 | **Instruction selection** — **выбор инструкций (команд)**. 38 | 39 | **Intermediate representation (IR)** — **промежуточное представление**, **внутренний язык**, **промежуточный язык** [4]. 40 | 41 | **Intrinsic function** — **внутренняя функция**, **встроенная функция**. 42 | 43 | **Lexical analysis** — **лексический анализ**, **лексический разбор**. 44 | 45 | **Middle end** — **фаза оптимизации** [5], **фаза оптимизирующих преобразований**, **средний план**. 46 | 47 | **Parsing (syntax analysis)** — **синтаксический анализ**, **синтаксический разбор**. 48 | 49 | **Partial evaluation** — **частичное вычисление**. 50 | 51 | (Compiler) **Pass** — **просмотр**, **проход**, **фаза**. 52 | 53 | **Peephole optimisation** — **локальная оптимизация**, можно встретить переводы **глазковая оптимизация**, **оконная оптимизация** и **покадровая оптимизация** [5]. Исторически peephole optimization это конкретный прием с просмотром и заменой в списке нескольких последовательных низкоуровневых команд. Сегодня данный термин используется для описания произвольных локальных правил оптимизации. 54 | 55 | **Semantic analysis** — **семантический анализ**, **контекстный анализ** [5]. 56 | 57 | **Static single assignment form (SSA)** — **форма со статически однократным присваиванием**. 58 | 59 | **Register allocation** — **распределение регистров**. 60 | 61 | **Value numbering** — **нумерация значений**. 62 | 63 | ## Источники 64 | 65 | 1. Евстигнеев В. А., Касьянов В. Н. Толковый словарь по теории графов в информатике и программировании. – Новосибирское отделение издательства" Наука", 1999. 66 | 2. Касьянов В. Н., Евстигнеев В. А. Графы в программировании: обработка, визуализация и применение. – СПб. : БХВ-Петербург, 2003. 67 | 3. Любимский Э. З., Поттосин И. В., Шура-Бура М. Р. От программирующих программ к системам программирования //Становление новосибирской школы программирования. – Новосибирск: Институт систем информатики им. АП Ершова СО РАН, 2001. – С. 27-18. 68 | 4. Богданов В. В., Ермаков Е. А., Маклаков А. В. Программирование на языке АЛМО. – Статистика, 1976. 69 | 5. Касьянов В. Н. Оптимизирующие преобразования программ. – Федеральное государственное унитарное предприятие Академический научно-издательский, производственно-полиграфический и книгораспространительский центр Наука, 1988. 70 | 6. Ершов А. П., Шанский Н. М. Термонологический словарь по основам информатики и вычислительной техники. – Просвещение, 1991. 71 | 7. Антон Подкопаев, Computer Science Center. Курс «Семантика языков программирования» (весна 2022). 72 | 8. Пирс Б. Типы в языках программирования. - «Лямбда пресс» & «Добросвет», 2011. 73 | -------------------------------------------------------------------------------- /docs/general.md: -------------------------------------------------------------------------------- 1 | ## Базовые учебники 2 | 3 | Книги, в которых освещаются основные вопросы построения компиляторов на серьезном, теоретическом уровне. 4 | 5 | Что я жду от современного учебника по компиляторам? Традиционно, упор в подобных работах делался на синтаксический анализ, как на наиболее формализованную и интересную чистым теоретикам область. Но для практика синтаксический анализ как раз наименее интересен и важен, по сравнению с остальными стадиями транслятора. В современной книге задачам синтаксического анализа лучше отвести от силы 10-15% общего объема текста, не более. 6 | 7 | Многие современные языки являются мультипарадигменными, что сильно усложняет задачу семантического анализа и последующих преобразований. Прошло время, когда можно ограничится рассмотрением единственного Паскале-подобного входного языка. 8 | 9 | Полезно смотреть на задачу компиляции, как на конвейер, состоящий из множества маленьких компиляторов. Каждый такой миниатюрный компилятор, достаточно просто устроен. Он переводит одно из многочисленных промежуточных представлений в другое. С вышесказанным связаны трансформационный подход, подход на основе переписывания термов и другие. Сюда же относится сам нелегкий выбор промежуточных представлений-языков. 10 | 11 | Теме анализа потоков данных и потоков управления отведены многочисленные монографии. Статический анализ востребован и за пределами классической задачи компиляции. Сюда можно отнести и абстрактную интерпретацию, символические вычисления и прочее. 12 | 13 | Задачи выбора, планирования инструкций, распределения регистров сильно усложнились с использованием современных проблемно-ориентированных процессоров, крупноблочных реконфигурируемых матриц и других нетрадиционных целевых архитектур. Отдельная, большая и очень актуальная задача для компилятора -- автоматизация распараллеливания на разных уровнях. 14 | 15 | Все еще мало освещены в литературе вопросы быстрого построения компиляторов, способы выразительного описания отдельных стадий трансляции. 16 | 17 | **A. Appel. Modern Compiler Implementation in ML** 18 | 19 | *Комментарий от @true-grue*. Серьезный академический учебник. При не таком уж большом объеме (всего 385 страниц) содержит массу полезных сведений и современных техник. Как и положено современному учебнику, упор сделан не на синтаксический анализ (ему отведено менее 60 страниц), а на более поздние стадии. Изложение иллюстрируется кодом на строгом и лаконичном языке ML. От раздела к разделу автор вместе с читателями движется в сторону построения компилятора для учебного языка Tiger, который имеет императивные и функциональные черты. Вот некоторые темы из учебника: проверка типов и упрощение выражений, выбор и планирование инструкций, распределение регистров, анализ потоков данных, сборка мусора, оптимизации циклов, форма SSA. Начальный раздел учебника содержит краткое введение в ML, но от читателя потребуется знакомство с функциональным программированием. Учебник можно рекомендовать всем, кто хочет получить основательный фундамент по теме и, при этом, сразу приобщиться к изящному стилю написания компилятора (стиль этот, увы, до сих пор не используется в большинстве популярных компиляторов). Избегайте Java- и C- версий книги. Они написаны в соавторстве и в них исходный посыл книги (ML-версия является оригиналом) сильно искажен. 20 | 21 | *комментарий от @vkazanov*. К сожалению, оригинальный учебник на ML читать не довелось, но могу прокомментировать версию на Си. Книга не так плоха, как говорит @true-grue, и описывает все ключевые аспекты современного компилятора. То есть *текст* в книге аккуратный и интересный. Беда же издания в том, что автор (и, видимо, соавторы) явно на актуальном на тот момент промышленном Си никогда не писал. Большая часть кода отформатирована так, чтобы быть похожей на условный язык программирования семейства ML. Никаких специфичных для компиляторов на Си приемов не используется. Например, в самом начале книги автора просто говорит, что не хочет заниматься высвобождением памяти. И не занимается! Даже человеку, привычному к Си, такие листинги читать будет сложно. Выходит, что суть и соль книги - код комплятора - решительно невозможно где-то применять. 22 | 23 | *комментарий от @vkazanov*. Прочитал, наконец, вариант книги на ML. Присоединяюсь к положительному комментарию @true-grue: это одна из лучших практических книг по бэкэндам компиляторов! Здесь рассматриваются все необходимые практические аспекты разработки бэкэндов компиляторов, причем не забыта и портативность - машино-зависимые аспекты вынесены в абстрактные модули. Язык автора лаконичный, точный и понятный, как и в других его книгах и публикациях. Кроме того, из книги видно, почему разработчики компиляторов так любят семейство языков ML. В сравнении с вариантом на простом Си (или с известными мне компиляторами на С++) кода совсем немного, и его можно легчо читать даже без глубоких знаний ML. 24 | 25 | **K. Cooper. L Torczon. Engineering a Compiler. Second Edition** 26 | 27 | *комментарий от @vkazanov* Со вторым изданием не знаком, но первое издание - неплохое общее введение в основные аспекты компиляторов. У авторов очень приятный стиль изложения материала, они скорее стараются передать идею, нежели дать строгий формализм, не в пример классической "Книге дракона". В отличие от последней большая часть материала посвящена всему тому, что компилятор делает уже после этапов синтаксического/семантического разбора. Главный недостаток книги - недетский объем, т.е. ее сложно читать последовательно. Это не какой-то единый фреймворк по построению компиляторор, а набор вводных глав плюс библиография для углубленного изучения тем. 28 | 29 | *Комментарий от @true-grue*. Изложение ведется в довольно занудном тоне, книгу нельзя назвать компактной. Но этот учебник на сегодняшний день -- лучший по общим вопросам компиляции. Это не должно удивлять, ведь авторы данного учебника являются признанными специалистами в своей области. С этой книги можно начинать знакомиться с современными методами анализа и трансформации уровня промежуточных представлений. Здесь вы найдете актуальную информацию по SSA, в том числе и по распределению регистров с использованием SSA. 30 | 31 | **T. Mogensen. Introduction to Compiler Design (2017)** 32 | 33 | **D. Grune et al. Modern compiler design (2012)** 34 | 35 | *комментарий от @vkazanov* Книга немного похожа на "Engineering a Compiler", про которую я писал выше как объемом, так и подходом. Автор в этой и другой своей книге ("Parsing Techniques - A Practical Guide", которая есть в списке ниже) стремится дать общий обзор тем, с упором на то, что интересующиеся читатели сами ознакомятся с деталями по ссылкам в библиографии. В отличие от книги Купера здесь значительно меньше уделяется внимания оптимизирующим преоборазованиям, но больше аспектам, связанным с реализацией конкретных семейств языков программирования (функциональных, объектных, параллельных, логических). 36 | 37 | **C. Fisher et al. Crafting A Compiler (2009)** 38 | 39 | **W. Waite. G. Goos. Compiler Construction (1995)** 40 | 41 | **Compilers: Principles, Techniques, and Tools. 2nd Edition** 42 | 43 | ## Книги по специальным вопросам компиляции 44 | 45 | Учебники и справочники для тех, кто уже знаком с основами теории компиляции. 46 | 47 | **Steven Muchnick. Advanced Compiler Design and Implementation (1997)** 48 | 49 | *Комментарий от @true-grue*. Данный учебник хорошо иллюстрирует высказанную выше мысль: современный учебник по компиляторам -- это вовсе не про грамматики и синтаксический анализ. Данные темы у Мучника отсутствуют полностью. И при этом учебник считается до сих пор одним из лучших по компиляторам! Книгу отличает энциклопедический охват материала по всем важнейшим стадиям компиляции. В некоторой степени текст уже устарел, но богатый авторский опыт и хорошая организация материала сами по себе очень ценны. В целом, это, скорее, не учебник, а справочник, который, тем не менее, читать очень увлекательно. 50 | 51 | **R. Wilhelm and H. Seidl. Compiler Design: Syntactic and Semantic Analysis** 52 | 53 | **R. Wilhelm and H. Seidl. Compiler Design: Analysis and Transformation** 54 | 55 | **R. Wilhelm and H. Seidl. Compiler Design: Virtual Machines** 56 | 57 | **R. Wilhelm, D. Maurer. Compiler Design (1995)** 58 | 59 | **Dick Grune and Ceriel J.H. Jacobs. Parsing Techniques - Second Edition (2008)** 60 | 61 | *Комментарий от @alexanius* Хотя классические книги по компиляторам начитаются с построения лексических и синтаксических анализаторов, отдельных пособий по их созданию довольно мало. Книга Дика Грюна и Кериела Якобса как раз и является таким редким экземпляром. В книге рассказывается про принципы построения распознавателей грамматик, достаточных для создания компилятора. Краткие теоретические сведения, описания алгоритмов и большое количество примеров делают книгу приятной и интересной для прочтения. Разумеется, написать свой распознаватель можно и без сведений из книги, но она поможет глубже понять принципы построения синтаксических анализаторов. Отдельно стоит заметить что книги Грюна обладают некоторой широтой рассматриваемых тем, что отличает их от аналогов, и проявляется в рассматриваемой книге. 62 | 63 | **Y.N. Srikant and Priti Shankar. The Compiler Design Handbook: Optimizations and Machine Code Generation (2002)** 64 | 65 | **Y.N. Srikant and Priti Shankar. The Compiler Design Handbook: Optimizations and Machine Code Generation, Second Edition (2007)** 66 | 67 | **Bob Morgan. Building an Optimizing Compiler (1998)** 68 | 69 | *Комментарий от @vkazanov*. Неожиданная книга. Это не учебник и не обзорная работа, а скорее описание оптимизирующего компилятора и логики основных архитектурных решений. Для такого рода описательной книги материал изложен очень даже читаемо; другое дело, что реального кода компилятора никто не прилагает, а все алгоритмы изложены в псевдокоде. Лично мне книга показалась интересной, но не думаю, что могу ее в общем случае рекомендовать. 70 | -------------------------------------------------------------------------------- /docs/general_ru.md: -------------------------------------------------------------------------------- 1 | # Учебники по компиляторам от русскоязычных авторов 2 | 3 | ## А.П. Ершов. Введение в теоретическое программирование (беседы о методе) 4 | 5 | ## В.Н. Касьянов, И.В. Поттосин. Методы построения трансляторов 6 | 7 | ## В. Касьянов. Оптимизирующие преобразования программ 8 | 9 | ## В. Касьянов, В. Евстигнеев. Графы в программировании: обработка, визуализация и применение 10 | 11 | ## Ю.Г. Карпов. Основы построения трансляторов (2005) 12 | 13 | *Комментарий от @true-grue*. Пусть вас не вводит в заблуждение название книги. Эта работа не по компиляторам, а по языкам, грамматикам и синтаксическому анализу. Надо сказать, что материал достаточно подробный, с интересными примерами. В тексте место отводится даже методам Эрли и CYK. Судя по всему, есть еще советское издание данного учебника (1982), но чем оно отличается от рассматриваемой версии -- мне неведомо. 14 | 15 | ## [С.З. Свердлов. Языки программирования и методы трансляции (2007)](http://publ.lib.ru/ARCHIVES/S/SVERDLOV_Sergey_Zalmanovich/Sverdlov_S.Z._Yazyki_programmirovaniya_i_metody_translyacii.(2007).[djv-fax].zip) 16 | 17 | *Комментарий от @impworks*. Подробный и понятный материал на русском языке, хорошо подходит для новичков. В равной мере освещаются как теоретические, так и практические вопросы создания транслятора высокоуровневого языка. Примеры на Pascal, разрабатываемый в качестве примера язык - подмножество Oberon. 18 | 19 | *Комментарий от @true-grue*. В книге имеется много отсылок к истории, а также рассуждений о языках программирования с позиций виртовской школы. В целом, раздел по вопросам компиляции повторяет "Построение компиляторов" Вирта, но в несколько развернутом виде. При этом не всегда обосновывается выбор того или иного решения. Например, читателю не говорится о том, чем отличается алгоритм сортировочной станции от общего рекурсивного спуска. Другой пример: используется Форт в качестве промежуточного языка, но генератор кода создается для обычной стековой машины, уже без стековых комбинаторов Форта (DUP, DROP, SWAP, OVER). На эту тему автор делает лишь ремарку: "достаточно трудно представить, что компилятор может породить такой код". В целом, учебник свою задачу выполняет и интересен уже рассуждениями автора о языках, а также историческими отсылками. Но после выхода перевода виртовского "Построения компиляторов" рассматриваемый учебник получил сильного конкурента. 20 | 21 | ## А. В. Костельцев построение компиляторов и интерпретаторов 22 | Описывает создание учебного языка с использованием средств генерации парсеров BISON, BYACC, ZUBR. 23 | 24 | ## Опалева Э.А., Самойленко В.П. -Языки программирования и методы трансляции-БХВ (2005) 25 | Книга посвящена формальной теории грамматик. Очень качественно и понятно разобрана теория LR,LL парсеров, расписана классификации Хомского, машин Тьюринга, конечные автоматы НКА и ДКА. Материал аналогично книге Карпов Ю.Г. основы построения трансляторов, - однако подход к подачи материала отличается и в целом выглядит получше. 26 | -------------------------------------------------------------------------------- /docs/metacomp.md: -------------------------------------------------------------------------------- 1 | # Метавычисления 2 | 3 | ## Климов А.В., Романенко С.А. Суперкомпиляция: основные принципы и базовые понятия 4 | 5 | [https://keldysh.ru/papers/2018/prep2018_111.pdf](https://keldysh.ru/papers/2018/prep2018_111.pdf) 6 | 7 | _Комментарий от @ksromanov._ В статье рассказывается про то, что же именно скрывается под загадочным термином "суперкомпиляция". Для меня, 8 | если честно, до прочтения этой статьи сам термин был столь же загадочен, как "сепуление". Авторы же дают определение 9 | самого подхода и рассказывают про наиболее популярный метод суперкомпиляции — преобразование программ через построение 10 | графа конфигураций, развеивая туман магии. Далее подход раскрывается на синтетических примерах, 11 | базирующихся на числах Пеано. Примеры показывают как возможости, так 12 | и ограничения подхода. Затем авторами рассказывается про родство суперкомпиляции и специализации программ 13 | (проекций Футамуры), кстати с определением, что же такое "специализация". И, окончательно, 14 | даётся краткий экскурс в историю суперкомпиляции. 15 | 16 | Мне статья очень понравилась тем, что, с одной стороны, она обладает строгостью хорошей научной работы "старой школы", 17 | а с другой стороны написана приятным достаточно простым языком, облегчающим чтение. Хотя, конечно, мне пришлось перечитать 18 | её несколько раз. К сожалению, она рассматривает очень упрощённый модельный пример, недостаточно раскрывает специализацию, 19 | и, тем не менее, довольно объёмиста и сложна. По-хорошему, хотелось бы иметь учебник, позволяющий написать собственный суперкомпилятор. 20 | Возможно, наилучшим языком будет язык из семейства LISP. 21 | 22 | С.А. Романенко написал и продолжение этой статьи под названием «Суперкомпиляция: гомеоморфное вложение, вызов по имени, частичные вычисления» 23 | [https://keldysh.ru/papers/2018/prep2018_209.pdf](https://keldysh.ru/papers/2018/prep2018_209.pdf), 24 | более подробно раскрывающую детали реализации суперкомпилятора SPSC (https://github.com/sergei-romanenko/spsc). В ней также упоминается написанный на Scheme специализатор Unmix [https://github.com/sergei-romanenko/unmix](https://github.com/sergei-romanenko/unmix). 25 | -------------------------------------------------------------------------------- /docs/parsing.md: -------------------------------------------------------------------------------- 1 | # ЧАВо по лексическому и синтаксическому разборам 2 | 3 | # Что из общего почитать по теме? 4 | 5 | ## Dick Grune, Ceriel J.H. Jacobs. Parsing Techniques: A Practical Guide (Monographs in Computer Science) 2nd ed. 2008 Edition 6 | 7 | _пока пусто_ 8 | 9 | ## Шень А. Программирование: теоремы и задачи. 10 | 11 | _Комментарий от @ksromanov._ Приятно написанная книга для начинающих: хороший баланс между строгостью и понятностью, 12 | в последних двух главах просто и понятно рассказывается про некоторые типы контекстно-свободных грамматик, 13 | рассказывается про разные методы разбора, в том числе и метод рекурсивного спуска. Фактически, главы 15 и 16 14 | самодостаточны, и являются «дешёвым и сердитым» введением в задачу грамматического (синтаксического) разбора, чтобы понимать 15 | о чём вообще идёт речь, и как примерно всё устроено. 16 | 17 | ## A. Afroozeh, A. Izmaylova. Practical general top-down parsers 18 | 19 | https://pure.uva.nl/ws/files/36086100/Thesis.pdf 20 | 21 | _Комментарий от @gsvgit._ 22 | Хороший материал для желающих более глубоко изучить одно из современных направлений развития алгоритмов синтаксического анализа — обощённый нисходящий синтаксический анализ. Рассмотрены не только особенности алгоритма, но и такие вопросы как разрешение неоднозначеностей, подходы к data-dependent parsing. Работа интересна как сама по себе, так и представленными в ней ссылками на другие работы. 23 | 24 | ## Giorgios Robert Economopoulos. Generalised LR parsing algorithms 25 | 26 | https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=2ff74ea9a0147318bc19e30c6d0f72e29a5f92c3 27 | 28 | _Комментарий от @gsvgit._ 29 | Хороший материал для того, чтобы начать изучать различные варианты обобщённого LR разбора. От классического варианта Томиты, до современных модификаций типа BRNGLR или RIGLR. 30 | 31 | # Что почитать по инкрементальному разбору 32 | 33 | _пока пусто_ 34 | 35 | ## Чем отличаются лексический и синтаксический разбор? 36 | 37 | _пока пусто_ 38 | 39 | # Что использовать в качестве генераторов и комбинаторов для разных языков? 40 | 41 | ## C/C++ 42 | 43 | _Комментарий от @ksromanov._ 44 | 45 | 1. *flex/bison* — классическая связка генераторов лексического и синтаксического разбора. 46 | Работают с форматами *lex/yacc* соответственно. Не очень удобны для разработки парсеров, 47 | т.к. теряют типы при передаче в основную программу, но зато обладают феноменальной обратной 48 | совместимостью — _написал и забыл_. Можно быть уверенным, что написанная и отлаженная грамматика не потребует 49 | поддержки лет 20. 50 | 51 | ## OCaml 52 | 53 | _Комментарий от @ksromanov._ 54 | 55 | 1. *ocamllex/Menhir* — современная свзяка генераторов лексического и синтаксического разбора. 56 | *Menhir* по всем параметрам превосходит *ocamlyacc*, у него были несовместимые изменения, но давно. 57 | 58 | 2. *ocamllex/ocamlyacc* — классическая связка генераторов лексического и синтаксического разбора, 59 | аналогичная *flex/bison*, не теряет типы при передаче в основную программу. Аналогично 60 | *flex/bison* поддерживает совместимость. Увы, *ocamlyacc* устарел и постепенно меняется на *Menhir*. 61 | 62 | Грамматику, разработанную на *ocamllex/ocamlyacc* очень легко портировать на *flex/bison*, поэтому 63 | OCaml с этой связкой можно использовать для прототипирования. 64 | 65 | 3. *angstrom* — популярная библиотека комбинаторов. 66 | 67 | ## Haskell 68 | 69 | _Комментарий от @ksromanov._ 70 | 71 | 1. *alex/happy* — связка генераторов, используется в GHC, поэтому можно более-менее надеяться 72 | на стабильность. 73 | 74 | 2. *parsec* — классическая библиотека комбинаторов. Удобна и проста в использовании. 75 | По её мотивам написаны *megaparsec*, *attoparsec* и пр. 76 | 77 | ## Универсальные генераторы 78 | 79 | _Комментарий от @ksromanov._ 80 | 81 | 1. *ANTLR4* — универсальный инструмент: реализует и лексический, и синтаксический разбор, поддерживает очень широкий спектр возможностей по заданию грамматики и семантических действий, имеет несколько бэкендов для генерации кода на разных языках, может генерировать как традиционную CST + Visitor, так и событийно-ориентированную инфраструктуру, используется в ряде промышленных проектов. Сообщество пользователей ANTLR поддерживает довольно обширный [репозиторий грамматик](https://github.com/antlr/grammars-v4). 82 | 83 | 2. *BNFC* — универсальный инструмент схожий с *ANTLR4*, поддерживает языки Haskell, Agda, C, C++, Java, Ocaml. 84 | -------------------------------------------------------------------------------- /docs/plt.md: -------------------------------------------------------------------------------- 1 | ## Интерпретаторы 2 | 3 | [Steele, G., Sussman, J. The Art of Interpreter (pdf)](https://dspace.mit.edu/bitstream/handle/1721.1/6094/AIM-453.pdf) 4 | 5 | _Комментарий @gabriel-fallen_ 6 | 7 | На основе серии метациркулярных интерпретаторов рассматривается влияние некоторых языковых фич на возможность построения модульных программ. В частности, изучается взаимное влияние разных схем связывания имён переменных (динамическая и синтаксическая), изменяемого состояния и побочных эффектов в целом, а также идентичности объектов (object identity). В качестве модельных языков используются диалекты LISP. 8 | 9 | [Friedman, D., Wand, M. Essentials of Programming Languages](https://eopl3.com/) 10 | 11 | _Комментарий от @ksromanov._ 12 | 13 | (Заинтересованному читателю не составит труда найти PDF в сети Интернет) 14 | 15 | На основе серии интепретаторов подробно рассматриваются различные аспекты семантических особенностей разных языков, навеянных семейством ML (SML/OCaml/Haskell), правда полиморфизм почти не затрагивается. В качестве языка реализации используется обеднённый диалект Scheme (LISP), представленный в системе Racket (lang:eopl). Учебные языки намеренно делаются непохожими на Scheme, но авторы предоставили крайне удобную библиотеку-генератор лексеров/парсеров, по функциональности похожую на Antlr. Поэтому читатель может сконцентрироваться на абстрактном синтаксисе и семантике, изредка развлекаясь простыми конструкциями конкретного синтаксиса модельных языков. Сильной стороной книги являются чудесно проработанные главы про состояние и CPS (continuation-passing-style), чёткое разделение между Expressed Values и Denoted Values, ненавязчивое введение спецификаций (операционная семантика). Фактически, книгу можно использовать для овладения техникой CPS. Слабые стороны — это продолжение сильных: спецификации введены слишком расплывчато (после желательно прочесть [статью Г. Хаттона][hutton-123], отзыв см. ниже), абстрактная семантика дана в открыве от конкретной (многочисленные примеры и того, и другого можно увидеть в Essentials of Compilation). Вывод типов значительно лучше дан в Static Program Analysis А. Мёллера (см раздел [Статический и динамический анализ](analysis.md)). 16 | 17 | [Shriram Krishnamurthi, Programming Languages: Application and Interpretation](https://www.plai.org/) 18 | 19 | _Комментарий @gabriel-fallen_ 20 | 21 | Текущее третье издание является пересмотром и развитием предыдущих двух, нескольких "сопутствующих" учебников (HtDP, DCIC) и большого количества курсов, 22 | много лет читавшихся и продолжающих читаться автором в университете. 23 | 24 | Изложение построено вокруг реализации и последовательного расщирения простого учебного языка программирования. 25 | Автор начинает с простейших понятий и вычислений "на бумаге" при помощи подстановки, после чего переходит к компьютерной реализации, 26 | вводя представления о Дереве Австрактного Синтаксиса (Abstract Syntax Tree, AST) и вычислении арифметических выражений. 27 | Только после этого поднимается вопрос синтаксического разбора и расширения интерпретатора более сложными конструкциями, 28 | такими как условное выполнение и связывание локальных имён. Среди продвинутых фич рассматриваются макросы, включая вопрос гигиены, 29 | и ООП, как основанное на классах, так и на прототипах, вклюяая ссылки на себя, множественное наследование, миксины и трейты. 30 | 31 | Несмотря на фокус на динамических языках и интерпретации, большой раздел посвящён статической проверке типов. 32 | На элементарных примерах автор вводит базовые понятия, механизмы и нотацию теории типов, разбирает вопросы безопасности (safety) 33 | и здравости (soundness) системы типов, вывод типов и гибридную типизацию (gradual typing). 34 | 35 | Среди дополнительных вопросов рассматривается реализация реляционного программирования, ленивых вычислений, "реактивных" вычислений, и другие. 36 | 37 | Я бы рекомендавал этот учебник начинающим без математической подготовки в качестве простого введения в предмет, 38 | дающий очень широкий обзор тем, проблем и методов, таким образом формирующий фундамент для более тщательного и формализованного 39 | изучения вопросов реализации языков программирования. 40 | 41 | ## Формальная семантика 42 | 43 | [Graham Hutton, Programming Language Semantics, It’s Easy As 1,2,3][hutton-123] 44 | 45 | _Комментарий @gabriel-fallen_ 46 | 47 | Эта недлинная вводно-обзорная статья — 25 страниц — покрывает удивительно обширный спектр тем, и делает это предельно просто и понятно. 48 | Горячо рекомендую к прочтению как начинающим, так и там, кто уже в курсе — хотя бы для удовольствия. 49 | 50 | Хаттон демонстрирует 5 способов задания семантики: 51 | - денотационную 52 | - малого шага 53 | - контекстуальную 54 | - большого шага 55 | - абстрактные машины 56 | 57 | И ещё между делом вводит понятие индукции по правилам вывода, которое используется не только в семантике языков программирования и Computer Science, 58 | но и в математике в целом, наряду с математической и структурной индукцией. 59 | 60 | Главный "секрет", позволяющий покрыть такой объём материала — использование предельно простого модельного языка: арифметических выражений, 61 | состоящих только из чисел и сложения. Это же является и главным недостатком — в языке нет переменных, соответственно, всё разнообразие подходов 62 | к работе с ними, и вся сложность остаются "за бортом". Кроме того, сам автор указывает, что такой язык не позволяет продемонстрировать разницу 63 | между денотационной и семантикой большого шага: в данном случае они выглядят одинаково, а вот для более сложных языков могут сильно отличаться. 64 | 65 | Впрочем, примитивность рассматриваемого языка с головой компенсируется обилием ссылок на классические и современные статьи по разным 66 | подходам к формализации семантики и связям между ними. Среди прочего даются ссылки на аксиоматическую, алгебраическую, теоретико-игровую 67 | семантики и некоторые другие. Лично меня более всего заинтересовали статьи самого же Хаттона с соавторами, демонстрирующие систематический 68 | последовательный способ получения абстрактных машин и компиляторов из той или иной формальной семантики. 69 | 70 | ## Теория типов 71 | 72 | [Benjamin C. Pierce, Types and Programming Languages](https://www.cis.upenn.edu/~bcpierce/tapl/)
73 | [Бенджамин Пирс, Типы в языках программирования](https://www.chitai-gorod.ru/catalog/book/454756/)
74 | 75 | _Комментарий @gabriel-fallen_ 76 | 77 | (Заинтересованному читателю не составит труда найти PDF в сети Интернет) 78 | 79 | TaPL является, вероятно, самым часто советуемым введением в теорию типов и алгоритмы проверки типов, и выступает в качестве основного учебника 80 | на курсах во многих университетах по всему миру. Вполне заслуженно, нужно сказать. 81 | 82 | Изложение ведётся от самых основ, начиная с краткого обзора необходимых математических понятий и формализмов, и базового фундамента в виде нетипизированных 83 | (динамически типизированных) интерпретаторов арифметических выражений и λ-исчисления. Таким образом он является одновременно и вводным учебником в реализацию 84 | интерпретаторов на функциональных языках. 85 | 86 | Далее Пирс последовательно объясняет все основные вопросы и расширения терии типов: Simply-Typed λ-calculus, типизация (изменяемых) ссылок (references), 87 | типизация исключений, подтипирование (subtyping), рекурсивные типы, (параметрический) полиморфизм, экзистенциальные типы и типы высших порядков. 88 | 89 | Как уже упоминалось, каждая тема сопровождается рассмотрением программы на языке OCaml, реализующей проверку типов. Конечно же, существуют "переводы" TaPL 90 | и на другие языки программирования, в первую очередь Haskell. Учебник предлагает большое количество упражнений, в том числе на программирование, решение которых 91 | также можно найти на множестве языков. 92 | 93 | Таким образом, данная книга вкупе со всеми дополнительными материалами и обсуждениями, которые можно найти в Интернет, может выступать как учебником для начинающих 94 | разработчиков языков и систем типов, так и справочником по базовым системам и алгоритмам для продолжающих. 95 | 96 | [hutton-123]: https://www.cs.nott.ac.uk/~pszgmh/123.pdf 97 | -------------------------------------------------------------------------------- /docs/runtime.md: -------------------------------------------------------------------------------- 1 | # Литература по вопросам, относящимся к средам выполнения 2 | 3 | ## Виртуальные машины 4 | 5 | Шитый код 6 | 7 | [Bell J. R. Threaded code //Communications of the ACM. – 1973. – Т. 16. – №. 6. – С. 370-372.](http://home.iae.nl/users/mhx/Forth_Bell.pdf) 8 | 9 | ## JIT-компиляция 10 | 11 | [Aycock J. A brief history of just-in-time //ACM Computing Surveys (CSUR). – 2003. – Т. 35. – №. 2. – С. 97-113.](https://prism.ucalgary.ca/bitstream/handle/1880/45368/2001-689-12.pdf?sequence=2&isAllowed=y) 12 | 13 | 14 | [Tratt L. Fast Enough VMs in Fast Enough Time](https://tratt.net/laurie/blog/entries/fast_enough_vms_in_fast_enough_time.html) 15 | 16 | Подробное введение в (мета-)трассирующую JIT-компиляцию на примере PyPy + RPython. Разбираются (упрощённые) примеры построения и оптимизации трасс, строится "мост" к практическому использованию PyPy для реализации собственной языковой ВМ с JIT-компиляцией. 17 | 18 | 19 | [Carl Friedrich Bolz, Laurence Tratt, The Impact of Meta-Tracing on VM Design and Implementation, Science of Computer Programming, 98(3):402-421](https://tratt.net/laurie/research/pubs/html/bolz_tratt__the_impact_of_metatracing_on_vm_design_and_implementation/) 20 | 21 | Most modern languages are implemented using Virtual Machines (VMs). While the best VMs use Just-In-Time (JIT) compilers to achieve good performance, JITs are costly to implement, and few VMs therefore come with one. The RPython language allows tracing JIT VMs to be automatically created from an interpreter, changing the economics of VM implementation. In this paper, we explain, through two concrete VMs, how meta-tracing RPython VMs can be designed and optimised, and, experimentally, the performance levels one might reasonably expect from them. 22 | 23 | 24 | [Würthinger T, Wimmer C, Humer C, Wöß A, Stadler L, Seaton C, Duboscq G, Simon D, Grimmer M. Practical partial evaluation for high-performance dynamic language runtimes. InProceedings of the 38th ACM SIGPLAN Conference on Programming Language Design and Implementation 2017 Jun 14 (pp. 662-676).](https://chrisseaton.com/rubytruffle/pldi17-truffle/pldi17-truffle.pdf) 25 | 26 | Статья является отличным кратким введением в практическое использование фреймворка Truffle для тех, кто уже знает как производить парсинг исходного кода, построение и непосредственную интерпретацию AST (ещё полезно знать про inline caches). Даются примеры и произвдится сравнение скорости нескольких интерпретаторов промышленных динамических языков программирования: JavaScript, Ruby и R. 27 | 28 | 29 | ## Параллельное и конкурентное выполнение 30 | 31 | ## Сборка мусора 32 | 33 | [The Garbage Collection Handbook: The Art of Automatic Memory Management](https://www.amazon.com/Garbage-Collection-Handbook-Management-Algorithms/dp/1420082795) ([Web version](http://gchandbook.org/)) 34 | 35 | 36 | [Memory Management Reference](https://www.memorymanagement.org/) 37 | 38 | Веб-сайт, посвящённый вопросам управления памятью — как ручного, так и автоматического. Содержит 39 | - глоссарий 40 | - вводные статьи 41 | - список литературы 42 | - ответы на частые вопросы 43 | 44 | Статьи дают краткое представление о проблематике управления памятью от железа через операционную систему к уровню приложения. 45 | Упоминают базовые техники аллокации и рекламации памяти (трассировка, подсчёт ссылок). Кратко описывают подходы к управлению памятью 46 | в языках программирования, как распространённых, так и исторических. В основном ссылаются на соответствующие разделы глоссария. 47 | 48 | Сайт можно рекомендавать в качестве обзорного введения в тематику сборки мусора и как обширный справочный материал. 49 | 50 | 51 | [Reference Counting: Harder than it Sounds](https://www.playingwithpointers.com/blog/refcounting-harder-than-it-sounds.html) 52 | 53 | Блог-пост кратко и доходчиво разбирающий две основные проблемы подсчёта ссылок в многопоточной среде и перечисляющий (в виде ссылок на статьи) 54 | ряд подходов к решению этих проблем. 55 | 56 | 57 | ## Языковые машины 58 | 59 | Forth 60 | 61 | Smalltalk 62 | 63 | [Smalltalk-80: The Language and its Implementation; Adele Goldberg and DavidRobson](http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.pdf) 64 | 65 | Prolog 66 | 67 | Lisp 68 | 69 | Pascal 70 | 71 | Lua 72 | 73 | ## Среды выполнения 74 | 75 | Standard ML 76 | 77 | [Appel A. W. A runtime system //Lisp and Symbolic Computation. – 1990. – Т. 3. – №. 4. – С. 343-380.](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.35.4846&rep=rep1&type=pdf) 78 | 79 | Машинный код в системах с раздельной компиляцией 80 | 81 | [Levine John R. Linkers and Loaders (The Morgan Kaufmann Series in Software Engineering and Programming)](http://www.staroceans.org/e-book/LinkersAndLoaders.pdf) 82 | 83 | Книга раскрывает цель и ключевые особенности статического и динамического связывания, которые обычно пропускаются в теоретических курсах. 84 | 85 | [Stephen Kell Dominic P. Mulligan Peter Sewell, The Missing Link: Explaining ELF Static Linking, Semantically](https://www.cl.cam.ac.uk/~pes20/rems/papers/oopsla-elf-linking-2016.pdf) 86 | 87 | В статье рассказываются практические особенности процесса связывания с точки зрения информатики (Theoretical Computer Science). Объясняются особенности терминологии (link-speak), используемой в документации и работах, посвящённых редакторам связей. 88 | -------------------------------------------------------------------------------- /docs/sea_of_nodes.md: -------------------------------------------------------------------------------- 1 | # Sea of Nodes (SoN) 2 | 3 | SoN является графовым IR. Для понимания идей, лежащих в основе SoN, нужно иметь представление об SSA [1] и PDG [2]. 4 | 5 | IR SoN предложено Клиффом Кликом. Для начального введения полезно посмотреть его работы [3], [4] и [5]. Основные результаты имеются в диссертации Клика [6]. Результаты диссертации обсуждаются [здесь](http://static.squarespace.com/static/50030e0ac4aaab8fd03f41b7/50030ec0e4b0c0ebbd07b0e0/50030ec0e4b0c0ebbd07b268/1281379125883/). 6 | 7 | SoN используется в: 8 | 9 | * [Java HotSpot](https://wiki.openjdk.java.net/display/HotSpot/C2+IR+Graph+and+Nodes) (первый коммерческий компилятор с использованием SoN, описан в [7]) 10 | * [V8 TurboFan](https://v8.dev/docs/turbofan) 11 | * Graal [8] 12 | * Scala LMS [9] 13 | * [LibFirm](https://libfirm.github.io/) [13] 14 | 15 | Среди академических работ следует отметить анализ формальной семантики SoN [10], IR Thorin [11], использование SoN на этапе порождения кода [12]. 16 | 17 | ## Источники 18 | 19 | 1. Braun M. et al. Simple and efficient construction of static single assignment form //International Conference on Compiler Construction. – Springer, Berlin, Heidelberg, 2013. – С. 102-122. 20 | 1. Ferrante J., Ottenstein K. J., Warren J. D. The program dependence graph and its use in optimization //ACM Transactions on Programming Languages and Systems (TOPLAS). – 1987. – Т. 9. – №. 3. – С. 319-349. 21 | 1. Click C. From quads to graphs: An intermediate representation's journey. – Technical Report CRPC-TR93366-S, Center for Resesearch on Parallel Computation, Rice University, 1993. 22 | 1. Click C., Paleczny M. A simple graph-based intermediate representation //ACM Sigplan Notices. – 1995. – Т. 30. – №. 3. – С. 35-49. 23 | 1. Click C. Global code motion/global value numbering //ACM Sigplan Notices. – 1995. – Т. 30. – №. 6. – С. 246-257. 24 | 1. Click C., Cooper K. D. Combining analyses, combining optimizations //ACM Transactions on Programming Languages and Systems (TOPLAS). – 1995. – Т. 17. – №. 2. – С. 181-196. 25 | 1. Paleczny M., Vick C., Click C. The java hotspot TM server compiler //Proceedings of the 2001 Symposium on Java TM Virtual Machine Research and Technology Symposium. – 2001. – Т. 1. – №. S 1. 26 | 1. Duboscq G. et al. An intermediate representation for speculative optimizations in a dynamic compiler //Proceedings of the 7th ACM workshop on Virtual machines and intermediate languages. – ACM, 2013. – С. 1-10. 27 | 1. Rompf T., Odersky M. Lightweight modular staging: a pragmatic approach to runtime code generation and compiled DSLs //Communications of the ACM. – 2012. – Т. 55. – №. 6. – С. 121-130. 28 | 1. Demange D., Fernández de Retana Y., Pichardie D. Semantic reasoning about the sea of nodes //Proceedings of the 27th International Conference on Compiler Construction. – ACM, 2018. – С. 163-173. 29 | 1. Leißa R., Köster M., Hack S. A graph-based higher-order intermediate representation //Proceedings of the 13th Annual IEEE/ACM International Symposium on Code Generation and Optimization. – IEEE Computer Society, 2015. – С. 202-212. 30 | 1. Hjort Blindell G. Universal Instruction Selection : дис. – KTH Royal Institute of Technology, 2018. 31 | 1. Braun M., Buchwald S., Zwinkau A. Firm-a graph-based intermediate representation. – KIT, Fakultät für Informatik, 2011. 32 | -------------------------------------------------------------------------------- /docs/spec.md: -------------------------------------------------------------------------------- 1 | # Спецпроцессоры: обзор вводной литературы 2 | 3 | Здесь приведены источники для начального знакомства с вопросами проектирования и программирования спецпроцессоров. Предпочтение отдано обзорным работам и учебникам, которые произвели на меня наибольшее впечатление. 4 | 5 | ## 1. Почему спецпроцессоры важны 6 | 7 | ### Implications of Makimoto’s Wave 8 | 9 | Статья доступна [онлайн](https://www.shmj.or.jp/makimoto/pdf/makimoto_04_01.pdf). 10 | 11 | 12 | 13 | Волна (или маятник) Макимото демонстрирует, что интерес в микроэлектронике колеблется между специализированными решениями и решениями общего назначения. К примеру, в области игрового "железа" можно выделить несколько этапов: специализированные чипы для обработки 2d графики, программный доступ к экранному буферу, специализированные ускорители для 3d, вычисления общего назначения на графических процессорах. Судя по всему, потребность в высокоуровневой специализации останется, даже если в ближайшем будущем произойдет полный переход на FGPA-подобные однородные структуры или универсальный "программируемый кремний". 14 | 15 | ### Жизнь в эпоху «тёмного» кремния 16 | 17 | Статья доступна [онлайн](https://habr.com/ru/companies/intel/articles/158223/). 18 | 19 | Почему сегодня маятник Макимото склонился в сторону специализации вычислений? Разве нельзя просто продолжать увеличивать тактовую частоту, как в старые-добрые времена, или же наращивать число процессорных ядер общего назначения? Ответ: "темный кремний". 20 | 21 | ### A new golden age for computer architecture 22 | 23 | Видео доступно [онлайн](https://engineer.yadro.com/video/new-golden-age-of-computer-architecture/). 24 | Более ранняя статья доступна [онлайн](https://dl.acm.org/doi/pdf/10.1145/3282307). 25 | 26 | Знаменитые тьюринговские лауреаты, Паттерсон и Хеннесси, рассказывают, почему переход к предметно-ориентированным архитектурам (domain-specific architectures, DSAs) является исторически закономерным. 27 | 28 | ## 2. Об архитектурах 29 | 30 | ### Компьютеры на СБИС 31 | 32 | 33 | 34 | Этот двухтомник японских авторов (оригинал вышел в далеком 84-м!) пробудил у меня в свое время интерес к специализированным вычислениям. Многие процессорные архитектуры из этих книг до сих пор выглядят вполне передовыми: машины, управляемые потоком данных, редукционные машины, специализированные ЦОС-процессоры, машины для обработки символов, машины реляционной алгебры и так далее. 35 | 36 | ### Матричные процессоры на СБИС 37 | 38 | 39 | 40 | Книга С. Куна (оригинал вышел в 88-м году) о проектировании систолических массивов и волновых процессоров. Кун, кстати говоря, является одним из авторов систолических архитектур. Какое это имеет отношение к дню сегодняшнему? Архитектура современного ускорителя Google TPU тоже представляет собой систолический массив. 41 | 42 | ### Stack Computers: the new wave 43 | 44 | 45 | 46 | Книга доступна [онлайн](https://users.ece.cmu.edu/~koopman/stack_computers/index.html). 47 | 48 | Еще одна старая книга (89-й год), на этот раз о стековых архитектурах. Точнее говоря, об их новой волне: форт-процессорах. Характерное применение форт-процессора: радиационно-стойкий чип RTX2010 в системе управления спускаемым аппаратом межпланетной станции "Розетта". Меня же с языком Форт и форт-процессорами связывает многое, см. далее. 49 | 50 | ### Embedded Computing: A VLIW Approach to Architecture, Compilers and Tools 51 | 52 | 53 | 54 | Ссылка на [Amazon](https://www.amazon.com/Embedded-Computing-Approach-Architecture-Compilers/dp/1558607668). 55 | 56 | Считается, что автор книги, J. Fisher, и придумал VLIW. В реальности у архитектуры были и иные авторы, см. мою заметку [Вектор-инструкция: о советском происхождении VLIW](https://habr.com/ru/articles/573306/). В любом случае, книга вполне подходит для изучения архитектуры VLIW-процессоров в контексте специализированных вычислений. 57 | 58 | ### Microprocessor Architectures: From VLIW to TTA 59 | 60 | 61 | 62 | Ссылка на [Amazon](https://www.amazon.com/Microprocessor-Architectures-Wiley-Microwave-Optical/dp/047197157X). 63 | 64 | Книга от Henk Corporaal, который является архитектуры TTA. Книгу, к слову сказать, интересно читать, даже если нет особенного интереса к VLIW и TTA. В этом смысле заслуживает внимания 2-я глава под названием "Тенденции в компьютерной архитектуре" (эту главу можно найти в интернете). 65 | 66 | ### Parallel Computer Organization and Design 67 | 68 | 69 | 70 | Ссылка на [Amazon](https://www.amazon.com/Parallel-Computer-Organization-Design-Professor/dp/0521886759). 71 | 72 | Неплохой учебник о параллельных архитектурах. На мой взгляд, материал здесь излагается детальнее, чем в знаменитой Computer Architecture: A Quantitative Approach. 73 | 74 | ### Domain-Specific Hardware Accelerators 75 | 76 | Статья доступна [онлайн](https://cacm.acm.org/research/domain-specific-hardware-accelerators/). 77 | 78 | Обзорная статья о DSA. Что, как и на каком уровне аппаратно ускорять, как проектировать такие ускорители. 79 | 80 | ## 3. Вопросы проектирования 81 | 82 | ### Hints for Computer System Design 83 | 84 | Статья доступна [онлайн](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/acrobat-17.pdf). 85 | 86 | Советы по проектированию компьютерных систем от еще одного тьюринговского лауреата, Батлера Лэмпсона. Лишь часть этих советов относится к проектированию аппаратной части, но ведь проектировать аппаратуру разумно совместно с программной частью компьютерной системы. Более поздняя версия статьи, где упор делается на формальные спецификации, доступна [онлайн](https://arxiv.org/pdf/2011.02455). 87 | 88 | ### Оркестр играет без дирижера. Размышления об эволюции некоторых технических систем и управлении ими 89 | 90 | 91 | 92 | Ссылка на [издательство](https://urss.ru/cgi-bin/db.pl?lang=Ru&blang=ru&page=Book&id=45524). 93 | 94 | Научно-популярная книга (оригинал вышел в 1984-м году) о децентрализованных, синхронных и асинхронных системах. Один из ее авторов, Д. А. Поспелов, специалист в области искусственного интеллекта и автор ярусно-параллельной формы. Другой автор, В.И. Варшавский, один из крупнейших специалистов в области асинхронной логики. Децентрализация и асинхронность – среди наиболее перспективных подходов к проектированию энергоэффективных спецпроцессоров. 95 | 96 | ### Embedded System Design 97 | 98 | 99 | 100 | Книга доступна [онлайн](https://link.springer.com/book/10.1007/978-3-030-60910-8). 101 | 102 | Книга от одной из ключевых фигур в области программно-аппаратного проектирования (hw/sw codesign) – P. Marwedel. Это хорошо спроектированный учебник, который затрагивает все основные аспекты проектирования встраиваемых систем, то есть тех систем, где особенно часто используются спецпроцессоры. 103 | 104 | ### ПЛИС Xilinx. Языки описания аппаратуры VHDL и Verilog, САПР, приемы проектирования 105 | 106 | 107 | 108 | Ссылка на [издательство](https://www.techbook.ru/book.php?id_book=1082). 109 | 110 | Учебник И.Е. Тарасова, моего коллеги и научного руководителя. Упор на использование FPGA неслучаен – именно таким образом разрабатываются многие спецпроцессоры. 111 | 112 | ### Специализированные процессоры ASIP и способы их верификации 113 | 114 | Статья доступна [онлайн](https://www.electronics.ru/files/article_pdf/8/article_8744_872.pdf). 115 | 116 | Единственная статья на русском языке, описывающая уникальный инструмент ASIP Designer компании Synopsys. Этот инструмент предзначен для автоматизации проектирования спецпроцессоров: по высокоуровневому описанию автоматически строится RTL-модель, компилятор и симулятор. 117 | 118 | ### Customizable Embedded Processors: Design Technologies and Applications 119 | 120 | 121 | 122 | Ссылка на [Amazon](https://www.amazon.com/Customizable-Embedded-Processors-Technologies-Applications/dp/0123695260). 123 | 124 | Отличная, на мой взгляд, книга об автоматизации проектирования спецпроцессоров. Здесь, помимо прочего, представлены детали устройства ранней версии ASIP Designer. Кроме того, описан еще более передовой подход к проектированию: с использованием автоматического синтеза специализированных команд. 125 | 126 | ### Аппаратная компиляция: синтез специализированных ускорителей 127 | 128 | Видео доступно [онлайн](https://www.youtube.com/watch?v=Q6-h6R_e-04). 129 | 130 | В докладе показаны некоторые мои наработки по теме автоматизации проектирования спецпроцессоров. 131 | 132 | ## 4. Вопросы программирования 133 | 134 | ### Engineering a Compiler 135 | 136 | 137 | 138 | Ссылка на [издательство](https://shop.elsevier.com/books/engineering-a-compiler/cooper/978-0-12-815412-0). 139 | 140 | В отсутствие учебника по разработке DSL-компиляторов для спецпроцессоров приходится читать обычные учебники по компиляторам. Книга Cooper и Toczon выделяется среди таковых хорошим стилем изложения и широким охватом материала. "Книга Дракона", на мой взгляд, серьезно ей проигрывает. Это неслучайно, ведь K. Cooper – известный теоретик компиляторостроения. 141 | 142 | ### Reasoning About Program Transformations 143 | 144 | 145 | 146 | Ссылка на [издательство](https://link.springer.com/book/10.1007/b97654). 147 | 148 | Эта небольшая (236 c.) и малоизвестная книга посвящена статическому анализу и преобразованиям программ, от формы SSA и до полиэдральных представлений. Весьма увлекательное чтение! 149 | 150 | ### Optimizing Compilers for Modern Architectures 151 | 152 | 153 | 154 | Книга в [издательстве](https://www.amazon.com/Optimizing-Compilers-Modern-Architectures-Dependence-based/dp/1558602860). 155 | 156 | Классический учебник по основам распараллеливания и оптимизации циклов. Только надо учитывать, что с 2001-го года прогресс в этой области на месте не стоял. 157 | 158 | ### SSA-based Compiler Design 159 | 160 | 161 | 162 | Ссылка на [издательство](https://link.springer.com/book/10.1007/978-3-030-80515-9). 163 | 164 | Отличный современный источник информации о вариантах SSA-представления и его прикладных применениях. 165 | 166 | ### Instruction Selection: Principles, Methods, and Applications 167 | 168 | 169 | 170 | Книга доступна [онлайн](https://www.diva-portal.org/smash/get/diva2:951540/FULLTEXT01.pdf). 171 | 172 | При разработке компилятора для спецпроцессора особое внимание обычно приходится уделять генератору кода. В этом отношении очень хорошо, что есть книга, в которой описаны основные подходы к реализации выбора команд. Ведь команды в спецпроцессоре могут быть весьма замысловатыми! 173 | 174 | ### Instruction Level Parallelism 175 | 176 | 177 | 178 | Ссылка на [издательство](https://link.springer.com/book/10.1007/978-1-4899-7797-7). 179 | 180 | Еще один важный для спецпроцессоров аспект генерации кода – выявление статического параллелизма уровня команд. К слову сказать, один из авторов книги, А. Aiken, является достаточно известным в компиляторном мире специалистом. 181 | 182 | ### Richard Feynman and The Connection Machine 183 | 184 | Статья доступна [онлайн](https://longnow.org/essays/richard-feynman-connection-machine/). 185 | 186 | Это воспоминания о том, как знаменитый физик Р. Фейнман принимал участие в проекте по созданию и применению специализированного суперкомпьютера Connection Machine. Некоторые моменты мне очень близки и понятны по проектам в духе SEAforth (см. далее). 187 | 188 | ### Программирование мультикомпьютеров на кристалле семейства SEAforth 189 | 190 | Статья доступна [онлайн](http://sovietov.com/txt/seaforth/seaforth.html). 191 | 192 | Написано по мотивам моей работы в компании IntellaSys, где руководителем являлся автор языка Форт, Чак Мур. Проект был довольно безумный: многоядерный, матричный форт-процессор без общей памяти, с взаимодействием по модели CSP. Игроки в TIS-100 должны примерно понять, о чем идет речь. За рамками статьи остались супероптимизатор и [инструмент отображения графа программы на матрицу процессорных элементов](http://sovietov.com/app/mapper/mapper_demo.html). 193 | 194 | ### Математическое и алгоритмическое обеспечение создания компиляторов предметно-­ориентированных языков для специализированных вычислительных машин 195 | 196 | Диссертация доступна [онлайн](https://www.mirea.ru/upload/medialibrary/72e/Sopetov_dissertation.pdf). 197 | 198 | Моя кандидатская диссертация по вопросам автоматизации создания генераторов кода для спецпроцессоров. Основная идея: реализовывать фазы генерации кода, по возможности, совместно, формулируя соответствующие задачи декларативным образом и переводя их на язык SMT-решателя. 199 | 200 | ### Создание компиляторов для спецпроцессоров 201 | 202 | Видео доступно [онлайн](https://www.youtube.com/watch?v=1m8oAQCTSeY). 203 | 204 | Моя лекция для компиляторщиков Samsung R&D. Название говорит само за себя. 205 | -------------------------------------------------------------------------------- /docs/spec_images/aiken.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/aiken.jpg -------------------------------------------------------------------------------- /docs/spec_images/async.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/async.jpg -------------------------------------------------------------------------------- /docs/spec_images/cooper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/cooper.jpg -------------------------------------------------------------------------------- /docs/spec_images/custom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/custom.jpg -------------------------------------------------------------------------------- /docs/spec_images/fpga.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/fpga.jpg -------------------------------------------------------------------------------- /docs/spec_images/isel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/isel.jpg -------------------------------------------------------------------------------- /docs/spec_images/marwedel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/marwedel.jpg -------------------------------------------------------------------------------- /docs/spec_images/modern.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/modern.jpg -------------------------------------------------------------------------------- /docs/spec_images/par.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/par.jpg -------------------------------------------------------------------------------- /docs/spec_images/sbis.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/sbis.jpg -------------------------------------------------------------------------------- /docs/spec_images/ssa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/ssa.jpg -------------------------------------------------------------------------------- /docs/spec_images/stack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/stack.jpg -------------------------------------------------------------------------------- /docs/spec_images/syst.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/syst.jpg -------------------------------------------------------------------------------- /docs/spec_images/trans.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/trans.jpg -------------------------------------------------------------------------------- /docs/spec_images/tta.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/tta.jpg -------------------------------------------------------------------------------- /docs/spec_images/vliw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/vliw.jpg -------------------------------------------------------------------------------- /docs/spec_images/wave.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/true-grue/Compiler-Development/aefcf82bff792665b8514596ce767acc4bfd9366/docs/spec_images/wave.jpg -------------------------------------------------------------------------------- /docs/ssa_without_phi.md: -------------------------------------------------------------------------------- 1 | # SSA без phi-узлов 2 | 3 | Речь идет о варианте SSA, где используются базовые блоки с аргументами, вместо phi-узлов. В результате получается простой функциональный язык ("Functional SSA" [1]), в котором переход (jump) к выполнению очередного блока можно рассматривать, как вызов хвостовой рекурсивной функции. 4 | 5 | Один из первых вариантов функциональной формы SSA был реализован в компиляторе MLton. В сообщении [2] Matthew Fluet описывает историю создания промежуточного представления на основе SSA и критикует подход с phi-узлами. В первую очередь, можно согласиться с тем, что функциональная форма SSA оказывается проще для понимания. В этом отношении следует указать на замечательную лекцию по началам SSA от Frank Pfenning, где изложение начинается с варианта, где используются базовые блоки с аргументами [3]. 6 | 7 | Аргументы базовых блоков используются в представлении SIL компилятора Swift [4], в Cranelift [5] и LLVM MLIR. Некоторые преимущества подхода без phi-функций указаны в документе, описывающем представление LLVM MLIR [6]. 8 | 9 | В работе [7] имеется формализация данного подхода в контексте языка Haskell, а ее критику см. в работе [8]. 10 | 11 | ## Источники 12 | 13 | 1. https://www.cs.purdue.edu/homes/suresh/papers/hosc08.pdf 14 | 1. http://mlton.org/pipermail/mlton/2007-February/029597.html 15 | 1. https://www.cs.cmu.edu/~rjsimmon/15411-f15/lec/10-ssa.pdf 16 | 1. https://github.com/apple/swift/blob/master/docs/SIL.rst 17 | 1. https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md 18 | 1. https://mlir.llvm.org/docs/Rationale/Rationale/#block-arguments-vs-phi-nodes 19 | 1. https://www.microsoft.com/en-us/research/wp-content/uploads/2016/11/compiling-without-continuations.pdf 20 | 1. https://www.cs.purdue.edu/homes/rompf/papers/cong-icfp19.pdf 21 | -------------------------------------------------------------------------------- /docs/synthesis.md: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------------- /docs/tutorial.md: -------------------------------------------------------------------------------- 1 | # Кратчайшее введение в создание компилятора 2 | 3 | Давайте сделаем компилятор арифметических выражений. Такой, который переведет исходный текст в [обратной польской форме записи](https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C) (ее еще называют RPN или ПОЛИЗ) в промежуточный код стековой машины. Но у нас не будет интерпретатора стекового кода, как вы, возможно, могли подумать. Далее мы сразу переведем результат в представление на языке Си. То есть у нас получится компилятор RPN в Си. 4 | 5 | Кстати говоря, писать компилятор мы будем на Python. Но пусть это не останавливает тех, кто предпочитает какой-то иной язык программирования. Вот вам полезное упражнение: переведите приведенный код на ваш любимый язык. Или воспользуйтесь уже готовым переводом: 6 | 7 | # Начнем с синтаксического анализа 8 | 9 | ```Python 10 | def scan(source): 11 | tokens = source.split() 12 | return [(('Push', int(x)) if x[0].isdigit() else ('Op', x)) 13 | for x in tokens] 14 | ``` 15 | 16 | Что мы здесь сделали? Функция scan получает от пользователя строку в обратной польской форме записи ("2 2 +"). 17 | А на выходе мы получаем промежуточное представление. Вот такое, например: 18 | 19 | ``` 20 | [('Push', 2), ('Push', 2), ('Op', '+')] 21 | ``` 22 | 23 | Итак, мы уже получили компилятор. Но уж очень он несерьезный. Вспомним, что изначально речь шла о коде на Си. 24 | 25 | # Займемся трансляцией в Си 26 | 27 | ```Python 28 | def trans(ir): 29 | code = [] 30 | for (tag, val) in ir: 31 | if tag == 'Push': 32 | code.append('st[sp] = %d;' % val) 33 | code.append('sp += 1;') 34 | elif tag == 'Op': 35 | code.append('st[sp - 2] = st[sp - 2] %s st[sp - 1];' % val) 36 | code.append('sp -= 1;') 37 | return '\n'.join(code) 38 | ``` 39 | 40 | Что здесь происходит? Давайте посмотрим на вывод данной функции (на том же примере с "2 2 +"). 41 | 42 | ```C 43 | st[sp] = 2; 44 | sp += 1; 45 | st[sp] = 2; 46 | sp += 1; 47 | st[sp - 2] = st[sp - 2] + st[sp - 1]; 48 | sp -= 1; 49 | ``` 50 | 51 | Да, это уже похоже на код на Си. Массив st играет роль стека, а sp -- его указатель. Обычно с этими вещами работают виртуальные стековые машины. 52 | Вот только самой машины -- интерпретатора у нас-то и нет. Есть компилятор. Что нам осталось? Надо добавить необходимое обрамление для программы на Си. 53 | 54 | # Наш первый компилятор в готовом виде 55 | 56 | ```Python 57 | ST_SIZE = 100 58 | C_CODE = r"""#include 59 | int main(int argc, char** argv) { 60 | int st[%d], sp = 0; 61 | %s 62 | printf("%%d\n", st[sp - 1]); 63 | return 0; 64 | }""" 65 | 66 | 67 | def scan(source): 68 | tokens = source.split() 69 | return [(('Push', int(x)) if x[0].isdigit() else ('Op', x)) 70 | for x in tokens] 71 | 72 | 73 | def trans(ir): 74 | code = [] 75 | for (tag, val) in ir: 76 | if tag == 'Push': 77 | code.append('st[sp] = %d;' % val) 78 | code.append('sp += 1;') 79 | elif tag == 'Op': 80 | code.append('st[sp - 2] = st[sp - 2] %s st[sp - 1];' % val) 81 | code.append('sp -= 1;') 82 | return '\n'.join(code) 83 | 84 | 85 | def rpn_to_c(source): 86 | return C_CODE % (ST_SIZE, trans(scan(source))) 87 | 88 | 89 | print rpn_to_c('2 2 +') 90 | ``` 91 | 92 | Остается скомпилировать вывод данной программы компилятором Си. 93 | 94 | Вы все еще готовы продолжать? Тогда давайте обсудим, что у нас получилось. Есть один сомнительный момент -- наш компилятор транслирует константные выражения, а ведь их можно вычислить просто на этапе компиляции. Нет смысла переводить их в код. Но давайте пока считать, что какие-то аргументы могут попасть в стек извне. Например, из аргументов командной строки. Остановимся на том, что практический смысл нашей разработке можно придать и позднее. Сейчас же важно получить общее представление о построении простейших компиляторов, верно? 95 | 96 | # Компилятор с использованием формы SSA 97 | 98 | Вам нравится заголовок? SSA -- это звучит очень солидно для любого компиляторщика. А мы уже сейчас будем использовать эту самую SSA. Что это такое? Давайте двигаться по порядку. 99 | 100 | Мы генерируем в данный момент код на Си, безо всяких виртуальных машин. Но зачем нам тогда рудимент в виде операций со стеком? Давайте заменим эти операции работой с обычными переменными из Си. Причем, мы не будем экономить переменные -- для каждого выражения заведем новое имя. Пусть компилятор Си сам со всем этим разбирается. Получается, что у нас каждой переменной значение присваивается лишь однажды. А это, кстати говоря, и есть форма [SSA](https://ru.wikipedia.org/wiki/SSA). 101 | 102 | Вот наш новый компилятор. 103 | 104 | ```Python 105 | C_CODE = r"""#include 106 | int main(int argc, char** argv) { 107 | %s 108 | printf("%%d\n", %s); 109 | return 0; 110 | }""" 111 | 112 | 113 | def scan(source): 114 | tokens = source.split() 115 | return [(('Push', int(x)) if x[0].isdigit() else ('Op', x)) 116 | for x in tokens] 117 | 118 | 119 | def trans(ir): 120 | (stack, code) = ([], []) 121 | name_cnt = 0 122 | for (tag, val) in ir: 123 | if tag == 'Push': 124 | code.append('int t%d = %d;' % (name_cnt, val)) 125 | stack.append('t%d' % name_cnt) 126 | name_cnt += 1 127 | elif tag == 'Op': 128 | (a, b) = (stack.pop(), stack.pop()) 129 | code.append('int t%d = %s %s %s;' % (name_cnt, b, val, a)) 130 | stack.append('t%d' % name_cnt) 131 | name_cnt += 1 132 | return ('\n'.join(code), stack.pop()) 133 | 134 | 135 | def rpn_to_c(source): 136 | return C_CODE % trans(scan(source)) 137 | 138 | 139 | print rpn_to_c('2 2 +') 140 | ``` 141 | 142 | Обратите внимание -- стека в коде на Си уже нет, а работа с ним имитируется в процессе трансляции. На стеке, который используется в процессе компиляции, содержатся не значения, а имена переменных. 143 | 144 | Вот окончательный результат: 145 | 146 | ```C 147 | #include 148 | int main(int argc, char** argv) { 149 | int t0 = 2; 150 | int t1 = 2; 151 | int t2 = t0 + t1; 152 | printf("%d\n", t2); 153 | return 0; 154 | } 155 | ``` 156 | 157 | Похоже, пришла пора расширять возможности нашего входного языка, как вы считаете? И двигаться, на мой взгляд, здесь можно в направлении стековых языков, таких как Forth, Postscript, Joy или Factor. Конечно же, можно и пойти путем усложнения входного синтаксиса. Но все эти вопросы давайте оставим для следующих заметок. Успехов в построении компиляторов! 158 | -------------------------------------------------------------------------------- /docs/verification.md: -------------------------------------------------------------------------------- 1 | ## Формальная верификация 2 | 3 | [Daniel Patterson and Amal Ahmed, The Next 700 Compiler Correctness Theorems](https://dbp.io/pubs/2019/ccc/) 4 | 5 | _Комментарий @gabriel-fallen_ 6 | 7 | Почти 30 страниц (считая список литературы), посвящённых проблеме формальной корректности _раздельной_ компиляции. 8 | 9 | Статья описывает _спектр_ возможных теорем о корректности, как для whole-program, так и раздельной компиляции, и презентует обобщённый фреймворк, в который их можно поместить. 10 | 11 | Рассматриваются четыре возможных сеттинга верифицированной раздельной компиляции: 12 | 13 | - раздельные модули, собранные одним и тем же верифицированным компилятором из одного и того же исходного языка; 14 | - модули, собранные _разными_ компиляторами одного и того же исходного языка; 15 | - модули, полученные другим компилятором другого исходного языка но с той же выразительностью; 16 | - модули, полученные из исходного языка с большей выразительностью, семантику которого невозможно выразить в рассматриваемом исходном языке. 17 | 18 | Через эту призму авторы делают обзор большей части существующей литературы и результатов по части 19 | верифицированной компиляции, как раздельной так и нет. Поэтому статья может служить 20 | отличным введением в проблематику и знакомством с этой областью исследований. 21 | 22 | ## Тестирование компиляторов 23 | 24 | [A Survey of Compiler Testing](https://www.software-lab.org/publications/csur2019_compiler_testing.pdf) 25 | Junjie Chen, Jibesh Patra, Michael Pradel, Yingfei Xiong, Hongyu Zhang, Dan Hao, Lu Zhang 26 | ACM Computing Surveys Vol 53 Issue 1 Article No.: 4 pp 1–36, 2020 27 | 28 | https://dl.acm.org/doi/10.1145/3363562 29 | 30 | _Комментарий от @ksromanov._ Просто читаемый свежий обзор методов тестирования компиляторов. Статья охватывает тему с разных сторон, включая 31 | 32 | - построение тестовых наборов программ 33 | - определение того, ошибочна или нет компиляция 34 | - оптимизация процесса тестирования 35 | - обработка результатов тестирования 36 | 37 | Статья хорошо классифицирует подходы генерации тестовых программ, давая широкий обзор существующих проектов как по методикам генерации, так и по целевым языкам программирования. 38 | 39 | Таким образом, статью можно рекомендовать в качестве актуального и достаточно широкого введения в поле. Разумеется, для реальной работы нужны более глубокие познания, которые можно почерпнуть из библиографии статьи. 40 | --------------------------------------------------------------------------------