Создание языка программирования. Часть 0

Доброго времени суток Уважаемые Хабра пользователи! Не буду долго рассусоливать, расскажу лишь основное что подтолкнуло меня к написанию данной статьи, и к собственно разработке своего языка программирования.

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

В связи с этим, сразу даю ответ на вопросы «Зачем это надо?! Очередной велосипед написать? Заняться что ли нечем?» — делается это с целью удовлетворения интереса, а так же для того что бы такие же интересующиеся как я имели представление о том как это работает.

Теперь собственно к теории языков программирования. Посмотрим что на этот счет всеми любимая Википедия:

Язык программирования — формальная знаковая система, предназначенная для записи компьютерных программ. Язык программирования определяет набор лексических, синтаксических и семантических правил, определяющих внешний вид программы и действия, которые выполнит исполнитель (обычно — ЭВМ) под её управлением.

С этим все понятно, ничего сложного, все мы знаем что это такое.

О том, что предстоит сделать


1. Лексический анализатор. Модуль который будет проверять правильность лексических конструкций, которые предусмотрены нашим языком программирования.
2. Парсер. Данный модуль будет переводить код понятный человеку в поток токенов, которые в последующем будут исполняться или переводиться в машинный язык.
3. Обычно на этом месте стоит оптимизатор, но так как наша поделка является скорее игрушкой чем крупным проектом, я откажусь от оптимизатора. И теперь наши пути расходятся:
3.1. Транслятор. Данный модуль будет транслировать поток токенов полученных от парсера в машинный код. Данный подход используется в компиляторах
3.2. Исполнитель. Данный модуль выполняет команды записанные в виде потока токенов. Данный подход используется в интерпретаторах.

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

Немного о реализации


1. Для реализации транслятора будет использован язык программирования Python. Почему именно он? Потому что его я знаю лучше всех. К тому же, его типизация, а точнее ее полное отсутствие позволит сократить количество переменных используемых при написании кода.
2. Для реализации виртуальной машины так же будет использован Python.
3. Для сборки проекта будет использован PyInstaller, так как он позволяет упаковывать все в один файл, к тому же на данный момент можно собрать для Linux и Windows без особых заморочек.

Теперь к практике


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

1. Есть однострочные комментарии, начинаются со знака диеза (#) и продолжаются до конца строки.
2. Есть два типа данных (integer, string).
3. Есть возможность вывода информации на экран.
4. Есть возможность ввода значений с клавиатуры.

Напишем простенькую программу на нашем новом языке, с учетом правил которые мы только что сформулировали:

int a = 10;
	int b;
	
	str c;
	str name;
	
	c='Hello!!!';
	b=a+a+10;
	
	print(a);
	print(b);
	print(c);
	
	input(name);
	c = 'Hello '+name;
	
	print(c);

Вод собственно и все. Простенькая программка, которая демонстрирует возможности только что придуманного языка. На этом я думаю следует закончить.

В следующей части начнем написание своего велосипеда, который сможет выполнить код приведенный выше.
Share post

Similar posts

Comments 52

  • UFO just landed and posted this here
      +7
      Хотя бы часть из этого нужно сделать на регулярках. Нап̷р̕имер,́ ̨X҉M̵L͘.̧
        +2
        А игру? Игру тоже надо сделать!
        +2
        Поправьте код, не красиво)
        • UFO just landed and posted this here
            +5
            Доброго времени суток!
            Хотите поговорить об этом?
            • UFO just landed and posted this here
                0
                Про фасон шляпы и очков не забудьте уточнить, одного вашего критерия может быть недостаточно, слишком погрешность велика.
                • UFO just landed and posted this here
                    +5
                    «Доброго времени суток» — вполне обычный «макрос». Такой же, как и «Привет, %UserName%».
                    • UFO just landed and posted this here
                        –1
                        Вот именно. Только он не выполнился. Вы видите сам макрос, а не его результат

                        Потому что это программа, а не ее вывод. Процессор — это вы, читатель. Прочитали «времени суток», подставили, скажем, «вечер», с поправкой на падежи.
                        • UFO just landed and posted this here
                            0
                            Если в шаблоне «Привет, %UserName%!», то читатель Хабр должен прочитать «Привет, Хабр!»

                            Читатель не может прочитать в шаблоне значение с подстановкой. По определению. Шаблон — это шаблон, результат подстановки — это результат подстановки.
                            «Привет, %UserName%» — это шаблон. Сделать подстановку — ваша задача, как интерпретирующего текст.
                            а не изображать из себя «процессор».

                            Отчего же? Вы читаете текст, вы его разбираете, интерпретируете. Процессор в чистом виде, работающий по своей внутренней программе. Текст, который вы читаете — входные данные.

                            Как мне кажется, вы меня поняли. И закончим.

                            Я понял, что вы не поняли.
                            • UFO just landed and posted this here
                                –1
                                Сделать нужную подстановку, это не моя задача, а того, кто этот текст пишет и отправляет.

                                Ни разу. Вы — автор — написали текст программы. Или, например, XML файл со ссылкой на какой-то объект данных. Вы (автор) будете подставлять данные или тот (та сущность), кто будет выполнять/интерпретировать эту программу/шаблон?

                                Если макрос не работает, это у него проблема, его программы, а не моя (как читателя).

                                Так это он у вас в голове не работает. Это шуточный макрос, который подставляется читателем во время чтения. By design.

                                По моему вы сами запутались.

                                Да нет. Просто вы отчего-то не можете понять простую шутку, которую из-за этого приходится объяснять формально.
                                • UFO just landed and posted this here
                                    0
                                    Нет, я с самого начала пытаюсь вам объяснить шутку. Разными словами, так как вы не понимаете. Но вы отказываетесь понимать, что шутка — это шутка. Переходите на «вы придумываете теперь», будто я не заявлял этого изначально.
                      +1
                      Доброго времени суток.
                      Такое может называться скрипт-языком, годящимся в качестве клея для вызова апи? Реализация (coco/r + обертка).
                        +4
                        я вижу связь между тем, как человек говорит и тем, как он программирует

                        Честно, тоже хочу такую супер-способность. Вы, наверное, часто проводите собеседования?
                          +1
                          Такая зависимость есть по моему опыту — если человек не может связно изложить мысли, он не сможет написать программу. Но тут, кмк, перебор, натяжка.
                  +1
                  Доброго времени суток!
                  Вам сюда, чтоб два раза не повторяться. Уже достаточно обсосали, вроде…
                  +8
                  Все-таки лексический анализатор преобразует исходный код в набор токенов, а после него синтаксический анализатор (парсер) на основе полученного списка токенов генерирует иерархическую структуру, руководствуясь правилами данного языка.
                  Ошибки большей частью уже ищет семантический анализатор. Затем работает генератор промежуточного кода и так далее.
                  Не вводите людей в заблуждение.
                    +5
                    >Для этого определимся с минимальным синтаксисом языка:
                    >2. Есть два типа данных (integer, string).

                    Сразу типы данных? без лексем, операций, разделителей?
                    не серьезно
                      +7

                      <зануда-mode-on>
                      У меня недавно был юбилей — elixir стал 20м языком программирования, на котором я написал что-то для использования в продуктиве.


                      Так вот, на почти любом распространенном языке можно писать хорошо и аккуратно. То есть это не проблема языка. Обычно новый язык создают, когда существующих не хватает для решения какой-то задачи, либо они фундаментально не решают ее хорошо. Например, elixir очень эффективно использует ресурсы сервера и отлично работает в многопроцессорных/многоядерных системах, в то время как ruby в силу своей природы так не может. Поэтому вместо того, чтобы "накостылять" ruby и попробовать с помощью него решать задачи, для которых он не очень приспособлен by design, сделали elixir.


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


                      P.s. я тоже писал свой язык программирования лет 10 назад, поэтому не вижу в вашем начинании ничего плохого, но выносить его из песочницы все же следует после того, как вы поймете, что это действительно может быть полезно.
                      </зануда-mode-off>

                        +1

                        Но тут то проблема в том, что автор статьи не никак не может писать правильно.
                        Думаю, ему надо не просто язык изобрести, но придумать для себя язык-"сержант", который будет стоять у него над душой и его дисциплинировать: "Делай раз!!!, Делай два!!! Делай три!!! Переходим к подтягиваниям: 1, 2, 3, 4, 5, 6, 7, 8, 9!!! Упал-отжался: 1, 2, 3, 4, 5, 6, 7, 8, 9!!! Встать!!! Три круга — на время — бегоооом… арш!!!". А потом, после разработки языка, всласть на нём пописать что нибудь опенсурсное — чтобы выработать таки хороший стиль, как в старину вырабатывали каллиграфы свой почерк.
                        Нечто подобное представляет собой язык Ada но тут этого "сержанта" надо сделать куда жёсче: можно на основе компилятора от ады или её спарк-разновидности разработать такой вот свой велосипед, А если автор возьмётся за разработку велосипеда с С/С++ подобным синтаксисом — то у его велика и своя аудитория может появится — преподы вузов, которым надо научить по человечески писать на С/С++ своих студентов. Можно, например, прямо в таком велосипедном языке начать реализовывать автоматические проверки компилятором соблюдения стандартов MISRA программистом — ведь здесь цель — обучение "чистописанию"..

                          0

                          Ну в JS же сделали eslint :)

                        +4
                        А где практика?
                        Почему строки заканчиваются с точкой запятой?
                        Почему одинарные кавычки?
                        Почему print со скобками? Это функция? А где вы описали реализацию функций? А где она подключается, или она встроенная?
                        А почему первая и остальные строки сдвинуты табуляцией?
                        А как вы строку складываете со сторокой? Чем реализованы?
                        Как реализованы типы данных? Как вы определяете их размерность, особенно в случае со строкой?

                        Где демонстрация хоть чего-либо?
                          +7
                          Я больше склоняюсь к созданию некоего промежуточного звена между интерпретатором и компилятором. То есть к созданию языка программирования, который будет транслироваться в байт-код виртуальной машины, которую так же предстоит написать.

                          О, боги! Это называется транслятор. Транслятор в язык виртуальной машины.

                          То есть к созданию языка программирования, который будет транслироваться

                          Это не создание ЯП, это создание среды для его реализации. Где описание терминалов, лексем, синтаксиса? Где БНФ или аналоги?

                            0
                            Полное отсутствие типизации в Python???!!!
                              –1
                              мож c php перепутал?
                                0
                                Наверное, имеется в виду, что она динамическая. Можно сваливать все переменные целевого языка в один массив/словарь/что там у автора и не заморачиваться заранее его типизацией, аллокацией достаточного количества памяти и т.п.
                                0

                                Когда я учился — создание простого компилятора языка типа basic было одним из типов курсовиков 3-го курса.
                                (АВТФ автоматики и телемеханики)


                                Интересно, а сейчас это сойдет за курсовик и какие вообще курсовики дают на 3-м курсе.

                                  0
                                  Такие же. У нас по ТЯПиМТ (Теория ЯП и Методы Трансляции) на 4м курсе был курсовик по созданию транслятора простого ЯП по заданной спецификации. С использованием генераторов парсеров по заданной грамматике.
                                  0
                                  «сократить количество переменных используемых при написании кода.» — но зачем?! От куда такой критерий?
                                    0
                                    В Котлине вроде получилось)… Хотя не уверен, что была такая цель)
                                    0
                                    Во-первых, большое спасибо за статью! А во-вторых — вот человек хотел начать реально основательную серию статей о разработке своего ЯП, но первая же статья оказалась слита только потому, что по сути всем не понравился синтаксис готового языка, только вот о самой сути все как-то подзабыли, однако ведь так просто не читать такие статьи кому не надо, ни так ли? В итоге те, кого постоянно посещают мысли о создании своего ЯП (по разным причинам. Меня, например, полностью не устраивает ни один язык: Си просто мозгодробилен с его указателями, буферами и типизацией, Java полностью объектно-ориентирована даже там где это совершенно не нужно, у Питона в синтаксисе черт ногу сломит. Вот PHP реально крут и меня устраивает полностью и во всем, но его репутация уже окончательно подмочена школотой, клепающей на нем сайтики для игровых кланов на купленном на сэкономленные от школьных завтраков деньги. Ну и производительность, конечно, оставляет желать лучшего, ибо это обвертка для С, притом на зенде. А это как фреймворк какой-нибудь в эмуляторе запускать (что так и есть по сути)) вынуждены искать эти статьи на Хабре, в итоге 90% из них — «Пишем свой ЯП. Часть 0», не прошедшие даже дальше нулевой части (куда там до первой) по этой же причине, и только потому, что кому-то это не понравилось то, что на нем не понравилось. То есть ни себе ни людям. Однако плох ли сам рецепт хлеба, если кому-то не понравилось как он выглядит в итоге, так как плохо сфоткан, обстановка не та, и т. д.? Рецепт тебе дали, возьми сам и испеки по нему какой сам хочешь, чем критиковать. В чем проблема-то? В итоге вроде бы и скилов хватает, и желания, и вроде и время можно найти, однако знания в этой области получить реально негде, ибо для многих она совершенно новая, каким-бы офигенным программером бы ты ни был. Так и живем(
                                      0
                                      Вы плохо читали комментарии.
                                      Жалобы в основном на то, что в статье написано

                                      «Давайте напишем язык, для этого нам нужно а, б, в, г, д, е», но вот зачем и почему я так решил — ничего этого описывать не буду, просто приведу готовый кусок программы на новом языке, не поясняя почему я там написал все именно так, и что именно я хочу сделать в новом языке, чтобы он был лучше/хуже и вообще какая цель.
                                      Но что еще хуже — даже в этом куске готового кода есть невнятные противоречия.
                                        0
                                        Это я понимаю, просто суть статей такого рода заключается именно в том, как создавать сам язык от, и до, а это общие правила, поэтому что на нем получится — уже не важно. Вот я и говорю, не на том внимание зацикливают. И зря.
                                          0
                                          Так а что собственно полезного и нового в данной статье? Именно то, чего ожидалось — примеров или каких-либо пояснений — в нем нет
                                            0
                                            Давайте даже распишу подробнее, что именно мне лично не понравилось, и разберем, что предлагает автор и что он делает на самом деле:
                                            1. Есть однострочные комментарии, начинаются со знака диеза (#) и продолжаются до конца строки.
                                            2. Есть два типа данных (integer, string).
                                            3. Есть возможность вывода информации на экран.
                                            4. Есть возможность ввода значений с клавиатуры.


                                            Далее следует код, в котором;
                                            1. Нет ни одного комментария. Нигде.
                                            2. Есть int и string, но заранее не поясняется, как должны объявляться переменные, как они могут присваиваться, одинарные кавычки или двойные нужно использовать для строк и должна ли быть разница, в конце кода даже идет сложение двух стрингов, что на самом деле операция посложнее, потому что неясно что будет если подставить string + int или int + string — то есть это выглядит как «мы напишем простенький пример типа 1 + 2, смотрите: sqr(100%-8/(4^3))/sin(-1^5).»
                                            3. пример с print() — синтаксис команды — почему нужно брать в скобки? интуитивно подразумевается, что в таком случае принт это функция, но о том что в нашем трансляторе уже создано понятие функции — нет. Для упрощенного примера, нужно было например «print a;»
                                            4. input() — тоже функция. И что будет если будет введен null неясно.

                                            То есть в статье много нелогичностей или даже противоречий. Если бы ее переделать — да, такие вещи нужны, но те в текущем ее виде.
                                              0
                                              С этим я совершенно согласен (спасибо за разбор, кстати), да и конкретно с этим я не спорил, тем более лично меня не удовлетворяет ни один существующий на сегодняшний день язык, поэтому было бы даже странно, если бы я принял предложенный автором синтаксис с визгом. Однако я говорю о другом: в том-то и дело, что вместо того, чтобы следить за выходом новых статей из цикла, которые будут постепенно открывать теорию (для тех, кому это нужно, конечно же), ее слили только потому, что print здесь «нужно брать в скобки», или как должны или не должны объявляться переменные, однако от внимания читателей как-то ушел тот факт, что статьи такого рода — это просто пособие. Рецепт тебе дан, дак пиши свой язык и бери print хоть в слеши, если ты не домохозяйка и пишешь все не чистым копипастом и поэтому можешь реализовывать по этому пособию то, что нужно конкретно тебе конечно же. Я не про Вас сейчас конкретно, а в общем.

                                              Я неспроста привел пример с хлебом, мне самому же он и понравился) Его на самом деле очень сложно печь. Не достаточно просто залить водой и перемешать все ингредиенты, опару для него нужно выстаивать сутки при определенной температуре, которую нужно чуть ли не градусником мерить постоянно, иначе он не поднимется и будет как куча военного клейстера с опилками. Что уж говорить о создании своего ЯП? В нулевой части автор, как этого и стоило ожидать, рассказал какая нужна емкость и какие ингредиенты. В следующих он уже бы рассказывал скорее всего как их нужно смешивать. Возможно в какой-либо части уже начнется непосредственно готовка. А то, что автор мешает все черенком от лопаты, потому-что ему удобнее, дак мешай венчиком, а хлеб испеки в форме домика для кукол если так хочется. Однако я сейчас зондирую почву по этой теме, и все статьи не прошли дальше 0 части и были слиты именно по этим же причинам: форма хлеба не понравилась. В итоге никто и не печет, ибо просто не по чему.
                                                +2
                                                вместо того, чтобы следить за выходом новых статей из цикла, которые будут постепенно открывать теорию (для тех, кому это нужно, конечно же), ее слили только потому, что print здесь «нужно брать в скобки»

                                                Нет, слили её потому, что она бесполезна. И остальные будут не лучше, так как автор сам не разбирается даже в теории! Вот цитата из статьи: "К тому же, его (питона) типизация, а точнее ее полное отсутствие позволит сократить количество переменных используемых при написании кода." Что и чему он сможет научить других людей? У автора есть спецификация языка? Полное описание синтаксиса? Модель памяти? Если есть — пусть сразу выложит. А пока — справедливые минусы.
                                                PS А эти аналогии с хлебом совсем не в тему.

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

                                                  Я косвенно могу предположить, что под словами «чему он сможет научить других людей» Вы подразумевали то, что автор вообще может дать людям с такими познаниями. Однако теория такого рода часто касается не совсем даже программирования. Дак вот отвечу, что если уж автор решился на написание целого курса статей, значит конкретно в этой области все-таки какие-то знания у него есть, их и хотелось получить. Наглядный пример: в хацкинге школьники и студенты разбираются часто лучше взрослых программистов (я сейчас не про возраст и постепенно отмирающий мозг), и ко всему прочему, он (хацкинг) часто бывает далек от классического программирования как такового (максимум это эксплуатация уязвимостей и клепание своих скриптиков для этого). В основном он выражается в поиске уязвимостей, а самое главное — возможностей для их эксплуатации. Реализация этого — дело десятое, на PHP легко писать, порог низкий, синтаксис простой, типизации нет. Дак вот если я хочу научиться ему у них — буду ли я воротить нос только потому, что в программировании как таковом полностью они не разбираются (даже в PHP по сути)? Они прекрасно разбираются в своей области, за чем я, собссно, к ним и обращаюсь.
                                                  0
                                                  «по этим же причинам: форма хлеба не понравилась»
                                                  Не форма, а рецепт — в нем не было «почему нужно брать именно этот компонент», «сколько его брать». Только немного философии
                                                    0
                                                    Дак ведь как я уже говорил выше — все это, очевидно, было бы раскрыто далее, если бы не такой теплый прием. Лично я даже на эту философию не обратил внимания. Часто при программировании приходится на SO разгребать тонны индусского кода, дабы из него уже склепать чего-то свое и нормальное. Вот я и говорю, мол, мог бы и вообще не программировать и на него не заходить, ибо рецепты там часто публикуют отвратные (и это на самом деле так). Однако нет, я извлекаю саму реализацию, то, с какой стороны человек решает эту задачу. Мог бы сидеть и днями на пролет анализировать какой плохой код там предлагается, но я благодарен людям (тем же индусам, которые предлагают почти 80% решений там), которые делятся своими знаниями и помогают другим, ибо только благодаря этому я понимаю как решить ту или иную задачу. Без этих… как-бы… пособий, я бы мог искать эту инфу где-нибудь в другом месте, либо штудировать документацию, где черт ногу сломит. Только что-то мне подсказывает, что я бы только этим бы и занимался. Так же и тут: на Хабре статей с похожей ситуацией 90%, поэтому придется теперь искать эту инфу где-то еще, но судя по всему я только и буду заниматься тем, чтобы собирать ее по крупицам из разных мест. Хорошо, если кто-то у себя в блоге все изложил, но вероятность мала. А ведь можно было бы все иметь в одном месте. Думаю, суть ясно донес насколько смог…
                                                      0
                                                      Непонятно, почему вы считаете, что «очевидно» это будет раскрыто далее.
                                                      Слабый уровень статьи как раз наоборот очевидно указывает, что не было бы раскрыто.

                                                      Все что есть в статье — общеизвестно, доступно, есть хотя бы на той же википедии (только там больше и подробнее), поэтому действительно непонятно, почему вы поддерживаете статьи, которые ну реально, совершенно ничего нового не дают.
                                                        0
                                                        Ну будем честны, я надеялся, не буду греха таить) А насчет Википедии — это интересно! Там это в общей статье по всем ЯП искать? Я же на безрыбье же все это) Ибо когда я мог бы изучать свойства ассемблера и устройство процессора, я занимался непосредственно программированием, вот и стою теперь в раскоряку…
                                            0
                                            Си просто мозгодробилен с его указателями, буферами и типизацией, Java полностью объектно-ориентирована даже там где это совершенно не нужно, у Питона в синтаксисе черт ногу сломит. Вот PHP реально крут и меня устраивает полностью и во всем, но его репутация уже окончательно подмочена школотой, клепающей на нем сайтики для игровых кланов на купленном на сэкономленные от школьных завтраков деньги


                                            Возьмите Delphi. Указатели использовать можно, но никто не заставляет. Совмещены объектно-ориентированная и императивная модель, как хотите, так и пишете. Приличная библиотека.
                                              0
                                              О, спасибо, да, в школе на нем на информатике игрались. Очень милый язык, подтверждаю, но просто блин. Ну Делфи же) Область применения практически нулевая, вакансий мало, развитие на чистом альтруизме. Да и все, что написано в наше время — это какие-то динозавры. Или я что-то путаю?
                                                0
                                                Я рассматривал с точки зрения «еще один язык (экосистема) в наборе умений, лишенный указанных недостатков» а не в плане построения карьеры конкретно на нем.
                                                  0
                                                  А, ну понятно. к сожалению на расширение «набора умений» на «еще один язык, лишенный указанных недостатков», как бы этого бы не хотелось, не достает свободного времени на такое вот программирование для души (в прямом смысле). Создание своего ЯП в этом случае является исключением, так как я вижу в этом практическую ценность конкретно для меня. Но за наводку спасибо) Жаль, на самом деле, что, как это часто бывает, действительно хорошие языки почивают в бозе, тогда как создаются всякие Свифты и Котлины, написанные неизвестно под какими препаратами (извините за прямоту, если задел, это просто мое мнение).

                                          Only users with full accounts can post comments. Log in, please.