Если очень кратко — это перевод на русский проекта The Super Tiny Compiler — проекта призванного помочь с изучением основ компилирования на рабочем примере.

image

Если хотите подробностей — прошу под кат. Если же нет — можно идти напрямую к переводу, он на гитхабе.

Что это, зачем это, почему это


Для тех кто не знает об этом проекте — это работающий компилятор Lisp-подобного языка в Си-подобный, написанный на JS. Процентов 90 кода покрыто подробными комментариями, и самих комментариев, в общем то, в 4 раза больше чем кода. В начале объясняются основы, терминология, а потом сам код.

А зачем это переводить? Английский же — язык программистов!


Всё началось с того что ссылка на этот проект у меня больше года провалялась в папке «на почитать». И вроде и штука интересная (10к+ звёзд на гитхабе, шутка ли), и мне интересно, но как как-то всё не находилось сил посмотреть и вникнуть. Почему? Да потому что оно на английском. А тут дело не в сложности, а в том что после 8-ми часового рабочего дня мозг напрочь отказывается читать на не родном языке что-то ещё. Вот протестует и всё тут. Поэтому решено было сделать перевод — и себе прочитать заодно, и другим помочь.



800+ форков. Из них — много попыток перевести на китайский, но на русском я ничего не нашёл (может оно и есть). Кстати, объясните, вот зачем люди форкают проекты а потом ничего в них не меняют?

А ты переводчик?


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

Что же касается перевода — он не дословный, незначительные слова могли быть упущены, кое-что добавлено от себя. Но при этом я старался передать суть на все 100%, так что в плане информативности перевод, вроде, получился равнозначным оригиналу.


Пример перевода. Скриншот кликабельный.

Так как оригинальный проект выложен на гитхабе — то и перевод я не стал закидывать целиком сюда. Для желающих ознакомиться: ссылка на перевод, ссылка на оригинал.

Приятного чтения!

P. S. Замечания принимаю хоть в комментариях, хоть в виде pull-реквестов, хоть в личку. Можете вообще делать форк и вносить изменения :)

По посту — надо ли (и как?) вешать плашку «перевод» на этот пост?

Комментарии (10)


  1. rraderio
    10.08.2018 12:07
    +1

    Кстати, объясните, вот зачем люди форкают проекты а потом ничего в них не меняют?
    Backup


    1. pewpew
      10.08.2018 12:29

      Ещё вариант — кнопкой ошибаются в гитхабе.


  1. ilammy
    10.08.2018 12:52

    Я когда-то перевёл целую книгу о том, как реализовывать Лиспы на Лиспе. Там есть и глава о том, как их компилировать в Си. Извиняюсь за саморекламу, но темы пересекаются.


    1. vlreshet Автор
      10.08.2018 13:04

      Ого. Серьёзная работа, снимаю шляпу


  1. bgnx
    10.08.2018 13:24

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


    пример однопроходного парсера
    const Code = '(substract (add 4 21) (mul 2 2))';
    
    let Position = 0;
    function parseExpr() {
        let number;
        if (parseSpace() && (number = parseNumber()) && parseSpace()) {
            return number;
        }
        let callExpr;
        if(callExpr = parseCallExpr()){
            return callExpr;
        }
    }
    function parseCallExpr(){
        let name;
        let args;
        if (parseSpace() && parseToken('(') && parseSpace() && (name = parseName()) && parseSpace() && (args = parseArguments()) && parseSpace() && parseToken(')') && parseSpace()) {
            return {
                type: 'CallExpression',
                name,
                args
            };
        }
        return null;
    }
    
    function parseArguments() {
        let expr;
        let args;
        if ((expr = parseExpr()) && ((args = parseArguments()) || true)) {
            return [expr, ...(args || [])];
        }
        return null;
    }
    
    function parseSpace(){
        let char = Code[Position];
        while (/ /.test(char)) char = Code[++Position];
        return true;
    }
    
    function parseNumber() {
        let current = Position
        let char = Code[current];
        var value = "";
        while (/[0-9]/.test(char)) {
            value += char;
            char = Code[++current];
        }
        if (value.length === 0) {
            return null;
        } else {
            Position = current;
            return {
                type: "NumberLiteral",
                value: value
            };
        }
    }
    function parseName() {
        let current = Position
        let char = Code[current];
        var value = "";
        while (/[a-zA-Z]/.test(char)) {
            value += char;
            char = Code[++current];
        }
        if (value.length === 0) {
            return null;
        } else {
            Position = current;
            return {
                type: 'Identifier',
                value: value
            };
        }
    }
    
    function parseToken(token) {
        let current = Position;
        let char = Code[current];
    
        let i = 0;
        char = token[i];
        while (Code[current] === char && i < token.length) {
            i++;
            current++;
            char = token[i];
        }
    
        if (i !== token.length) {
            return false;
        } else {
            Position = current;
            return true;
        }
    }
    
    console.log(JSON.stringify(parseExpr()));


    1. vlreshet Автор
      10.08.2018 13:38

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


  1. dynamic
    10.08.2018 16:41

    > токенизер
    «токенизатор» звучит все же лучше и привычней.


  1. true-grue
    10.08.2018 16:51

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

    На мой взгляд, разумно начать с причин, по которым с построением компиляторов важно знакомиться неспециалистам. Причины эти сегодня не так уж очевидны, помимо совсем уж тривиального — “изучение устройства инструмента может помочь в практической с ним работе”. Казалось бы, языков и компиляторов уже и так существует великое множество. А для исключительных случаев есть перенацеливаемые системы gcc и LLVM.

    Подробный ответ включал бы в себя DSL и порождение кода для экзотических архитектур (бытует расхожее мнение, что архитектура команд это нечто неизменное, и если хочется нового — следует брать RISCV, созданную специалистами мирового класса. В качестве возражения можно привести подходы с синтезируемой системой команд, ASIP, CGRA, HLS).

    Новые подходы к компиляции часто требуют перестройки архитектуры существующего компилятора. Так произошло, например, с популяризацией SSA. И, скорее всего, именно по такой причине в gcc и LLVM до сих пор отсутствует работа с графовым представлением, подобным sea of nodes, не говоря уже о более нишевых и более современных представлениях программы. Реализации современных подходов, и пусть это не кажется теперь странным, чаще можно найти в небольшом DSL-компиляторе.

    В коде данного проекта учебного компилятора можно встретить visitors. На мой взгляд, это неоднозначный выбор. Разумеется, использование данного шаблона проектирования — данность, обусловленная, во многом, преподаванием ООП/Java. Более того, visitors до сих пор можно встретить в реализациях некоторых “промышленных” компиляторов. Но начинающим, и это мое убеждение, следует демонстрировать вещи в наиболее прозрачной и естественной для соответствующего предмета изучения нотации. В хорошем учебнике по компиляторам вы не найдёте visitors. Сопоставление с образцом, которое этот шаблон с успехом заменяет, используется в наши дни даже в таких популярных и практичных языках, как Scala.

    Любопытно, что автор так и не воспользовался в своей реализации visitors методом exit, который соответствует обходу дерева снизу вверх. А ведь именно такой порядок обхода используется в проекте для реализации генератора кода. Здесь автор обошёлся лишь рекурсией и switch. Почему же не сделать того же и в остальных частях программы?

    Для знакомых с Лисп-подобными языками в качестве возможной альтернативы данному проекту я бы посоветовал очень хорошее введение Essentials of Compilation An Incremental Approach (https://jeapostrophe.github.io/courses/2017/spring/406/notes/book.pdf ). Не теряют актуальности и сегодня известные учебники Вирта (https://www.ozon.ru/context/detail/id/4803779/ ) и Эппеля (https://www.cs.princeton.edu/~appel/modern/ml/ ).

    Комментарий получается слишком пространным, но мне все еще не даёт покоя вопрос: а где же подобные введения на русском языке, оригиналы, а не переводы? Ведь предположение о том, что русскоязычные разработчики менее компетентны в области компиляторов, чем автор рассмотренного учебного компилятора, является абсолютно несостоятельным…


    1. vlreshet Автор
      10.08.2018 17:09
      +1

      Спасибо, рад что мой труд не прошёл даром.

      а где же подобные введения на русском языке, оригиналы, а не переводы
      ИМХО, вопрос менталитета. Американцы: «я выучил крутую штуку. пойду напишу в блог, расскажу всем что оно такое». Наши (СНГ): «я выучил крутую штуку. хрен я что кому подскажу, я мучился с документацией — вот и все остальные пусть мучаются». Как-то так. Не зря же есть шутка о зарубежных форумах и о наших — мол на зарубежном тебе всё подскажут и разжуют, а на наших назовут 10 причин почему ты дебил и вопрос твой говно.


      1. mihacoder
        12.08.2018 14:39

        Тут еще от форума зависит. Например, на форум CMS Opencart, как и везде, заходят новички с вопросами "как сделать...". И большинство ответов звучат типа "купи у меня вот этот модуль (ссылка), там это сделано". Хотя, если объяснить, там дел на 10 минут. На форумах по WordPress такого намного меньше, хотя они оба бесплатные, к обоим есть и платные, и бесплатные модули и плагины.