Как сделать свой язык

Добавил пользователь Дмитрий К.
Обновлено: 04.10.2024

Какими бывают искусственные языки, с кем можно на них общаться и смогут ли когда-нибудь все люди заговорить на одном языке.

Нашли опечатку или ошибку? Выдeлите фрагмент и нажмите Ctrl+Enter.

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

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

Искусственный язык — это лингвистическая система, целенаправленно созданная одним или несколькими авторами. Языковые системы начали разрабатывать в европейских странах в XVII-XVIII веках, когда роль латинского языка в обществе стала слабнуть.

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

Но это правило касается тех языков, которые разработаны для общения наряду с привычными естественными языками.

Какими бывают искусственные языки?

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

При этом есть и смешанные языки, в создании которых используются оба подхода.

Если говорить о назначении искусственных языков, то чаще всего выделяют:

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

Международные искусственные языки

Эсперанто
территория: Европа, Бразилия, Вьетнам, Иран, Китай, США, Япония
количество носителей: около 1-2 млн человек
особенности: в начальной форме существительные всегда заканчиваются на о, глаголы — на i, прилагательные — на а, наречия — на е.

Самый распространенный среди всех плановых языков — эсперанто. На нем говорят около 1-2 млн человек, а примерно для 2 тыс. эсперанто является родным с рождения.

Эта языковая система разрабатывалась в конце XIX века польским врачом-окулистом и по совместительству лингвистом Лазарем Людвиком Заменгофом.

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

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

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

Грамматика языка проста и состоит из 16 главных правил, в которых нет никаких исключений. Алфавит состоит из 28 букв: 23 согласные и 5 гласных.

7 слов на эсперанто

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

Логлан

территория: Северная Америка
количество носителей: ≈ 1500 человек
особенности языка: строгий порядок, логичность, отсутствие множественного числа у частей речи

Этот логический искусственный язык был создан в 1955 году социологом Джеймсом Куком Брауном. Он считал, что в естественных языках слишком много неточности и двусмысленности и задумал создать такой язык, в котором все строилось бы на основе исключительно логических выводов — logical language.

Сам язык состоит из трех основных частей речи: словечек, предикатов и имен.

Словечки в логлане играют роль союзов, предлогов и числительных в привычных для нас языках. Бывают простыми и составными.

А вот предикаты составляют основной смысл языка. Эти слова можно отличить от других частей речи в логлане по наличию стыка двух согласных в слове: takna — говорить, bukcu — книга, prano — бежать, бегущий. Вокруг предикатов всегда есть от одного до пяти слотов — места для других словечек или имен, дополняющих фразу. Заполнять все слоты не обязательно, но менять порядок слов в определенной фразе нельзя.

С предикатом takna можно составить такую фразу — X1(кто?) говорит с X2(кем?) о X3(о чем/о ком?) — Mi takna la Marias, la Djordj — Я говорю Марии о Джордже.

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

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

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

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

Python

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

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

Разрабатывать Python начал голландский программист Гвидо ван Россум в 1989 году.

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

На Python написаны графический редактор GIMP. Это язык применялся для разработки таких популярных игровых проектов, как Battlefield 2, World of Tanks. Python используют в работе многие известные компании. Весь сервис рекомендаций на Netflix создан на этом языке. Также с Python работают Walt Disney, YouTube, Instagram и даже NASA.

JavaScript

сфера применения: программный доступ к объектам в приложениях, создание интерактивных элементов на веб-страницах
особенности языка: динамическая типизация, интерпретируемый язык, все популярные браузеры поддерживают JavaScript
где учить: Современный учебник JavaScript

JavaScript начали разрабатывать в 1995 году две крупные IT-компании Netscape Communication Corporation и Sun Microsystems. При этом сам язык не принадлежит какой-либо корпорации. Первоначально проект назывался LiveScript, но позже был переименован в JavaScript, для того чтобы подчеркнуть сходство этого языка с уже известным в то время языком Java.

Повсеместно JavaScript применяется во фронтенд-разработке. С помощью его инструментов разрабатываются интерактивные интерфейсы приложений и страниц в Интернете. Вместе с HTML и CSS, он входит в базовый набор языков для разработки веб-сайтов.

Если говорить о веб-разработке, то он универсален, так как его поддерживают все востребованные операционные системы и браузеры.

Языки вымышленных рас

Квенья

Кстати, сам мир Средиземья фактически появился благодаря языку, а не наоборот, как было со многими другими языками из художественных произведений. Параллельно с тем, как Толкин работал над квенья, он описывал расу эльфов, которой и принадлежал язык.

Грамматика квенья сложная. Например, у существительных здесь девять падежей. Падежные окончания используются вместо предлогов, как и, например, в казахском языке. Также слова на квенья могут стоять в четырех разных числах: единственном, двойственном, множественном и собирательном.

5 слов на квенья

Клингонский

Клингонский создавался на основе языков североамериканских индейцев и санскрита. В нем много труднопроизносимых звуков и гортанных смычек.

5 повседневных фраз на клингонском

  • Pe’vIl mu’qaDmey — Хороших проклятий! (Пожелание хорошего дня)
  • Nuqjatlh? — Что ты сказал?
  • HIQaH! — Помогите!
  • Nuq 'oH ponglIj'e'?/. 'oH pongwIj'e' — Как тебя зовут?/Меня зовут …
  • Huch 'ar DaneH? — Сколько это стоит?

Языки для общения с внеземным разумом

Линкос

территория: вся Вселенная (в теории)
особенности: язык основан не на словах, а на математических понятиях и радиосигналах.

Мысль о подобных языках стала популярной, когда весь мир захватила идея исследования космоса, изучения ближайших планет, далеких галактик и путешествий по вселенной. В 1960 году Ганс Фройденталь, математик и профессор Утрехтского университета, задумал создать язык, на котором можно было бы объясниться с представителями инопланетных цивилизаций. Название ему дали первые буквы слов lingua cosmica — космический язык.

Он считал, что представители разумных инопланетных рас должны обязательно знать простейшие математические понятия: натуральные числа, отношения равенства и неравенства, убывание и возрастание.

Тема написания своего ЯПа не дает мне покоя уже около полугода. Я не ставил перед собой цель "убить" CoffeeScript, TypeScript, ELM, тысячи их, я просто хотел понять кухню и как они вообще пишутся.

К моему неприятному удивлению, большинство из этих языков используют Jison (Bison для JavaScript), а это не совсем попадало под мою задачу — "понять", так как по сути дела Jison делает все за вас, собирает AST по заданным вами правилам (Jison как таковой отличный инструмент, который делает за вас львиную долю работы, но сейчас не о нем).

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

Стоит заметить, что данное руководство не привязано к JavaScript, он выбран исключительно из соображений скорости разработки и читаемости, так что вы можете написать свой "лисп"/"питон"/"ваш абсолютно новый синтаксис" на любом знакомом вам языке.

Также до момента написании компилятора (в нашем случае транслятора), процесс написания языка не отличается от процессов создания языков компилируемых в ASM/JVM bitcode/LLVM bitcode/etc, а это значит, что данное руководство не ограничивается созданием языка трансляцируемого в JavaScript.

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

Немного теории

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

Что тут происходит:

1) Lexer

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

Т.е. на выходе из этого (CoffeeScript):

Мы получаем это (сокращенная запись):

Так-как CoffeeScript отступо-чувствительный и не имеет явного выделения блока скобками < и >, блоки отделяются отступами ( INDENT ом и OUTDENT ом), которые по сути заменяет скобки.

2) Parser

Парсер составляет AST из токенов (лексем). Он обходит весь массив и рекурсивно подбирает подходящие паттерны, основываясь на типи токена или их последовательности.

Из полученных токенов в пункте 1, parser составит, примерно такое дерево (сокращенная запись):

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

3) Compiler

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

Компилятор (читай транслятор) преобразует Абстрактно-Синтаксическое Дерево в JavaScript код:

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

Habrlang

Итак, разобравшись с теорией, нам предстоит собрать свой язык программирования, у которого будет примерно следующий синтаксис (что-бы не особо париться, мы будем делать смесь из Ruby, Python и CoffeeScript):

В следующей главе вы реализуем все основные классы нашего транслятора, и научим его транслировать комментарии Habrlang'а в JavaScript.

Техника креативности

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

Видели ли Вы когда-нибудь дорожные знаки? Вот Вам и предстоит создать по аналогии свою собственную систему.

Нужно всего лишь вырезать из толстого картона карточки и на каждой нарисовать по значку.

Ну а затем, работая над своей проблемой, формулируйте предложение, подставляя в него вместо слов . свои картинки.

Свой тренинговый центр за 69 000 руб. Можно вести бизнес онлайн!

В стоимость входят комплект материалов для очного проведения всех программ + 2 дня живого обучения онлайн. Бессрочное право проведения 10 программ. Никаких дополнительных отчислений и платежей. Запуск за 2 дня.

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

В чём смысл этой техники, которую в своё время придумали три архитектора: Александер, Исикава и Сильверштейн?

работая над смешными и ни к чему не обязывающими картинками, мы:

Во-первых,

А тем временем, в процессе увлекательной игры рождаются гениальные идеи.

Во-вторых,

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

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

Создаем свой собственный язык программирования и его компилятор

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

Если вы незнакомы с нижеприведенными понятиями, не беспокойтесь – мы проясним необходимость этих компонентов далее, по ходу создания компилятора. В качестве лексера и парсера используется PLY. В роли низкоуровневого языка-посредника для генерации оптимизированного кода выступает LLVMlite.

Таким образом, к системе предъявляются следующие требования:

  • Среда Anaconda (более простой способ для инсталляции LLVMlite – conda, а не классический pip)
  • LLVMlite
  • RPLY (то же, что PLY, но с более хорошим API)
    (статический компилятор LLVM)

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

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

Как для этой однострочной программы формально описать грамматику языка? Чтобы это сделать, необходимо использовать расширенную Бэкус – Наурову форму (РБНФ) (англ. Extended Backus–Naur Form ( EBNF )). Это формальная система определения синтаксиса языка. Воплощается она при помощи метаязыка, определяющего в одном документе всевозможные грамматические конструкции. Чтобы в деталях разобраться с тем, как работает РБНФ, прочтите эту публикацию.

Создадим РБНФ, которая опишет минимальный функционал нашей микропрограммы. Начнем с операции суммирования:

Соответствующая РБНФ будет выглядеть следующим образом:

Дополним язык операцией вычитания:

В соответствующем РБНФ изменится первая строка:

Наконец, опишем функцию print:

В этом случае в РБНФ появится новая строка, описывающая работу с выражениями:

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

Компилятор – это программа, переводящая текст ЯП на машинный или другие языки. Программы на TOY в этом руководстве будут компилироваться в промежуточное представление LLVM IR (IR – сокращение от Intermediate Representation) и затем в машинный язык.


Использование LLVM позволяет оптимизировать процесс компиляции без изучения самого процесса оптимизации. У LLVM действительно хорошая библиотека для работы с компиляторами.

Наш компилятор можно разделить на три составляющие:

  • лексический анализатор (лексер, англ. lexer)
  • синтаксический анализатор (парсер, англ. parser)
  • генератор кода

Для лексического анализатора и парсера мы будем использовать RPLY, очень близкий к PLY. Это библиотека Python с теми же лексическими и парсинговыми инструментами, но с более качественным API. Для генератора кода будем использовать LLVMLite – библиотеку Python для связывания компонентов LLVM.

1. Лексический анализатор

Итак, первый компонент компилятора – лексический анализатор. Роль этого компонента заключается в том, чтобы разделять текст программы на токены.


Воспользуемся последней структурой из примера для РБНФ и найдем токены. Рассмотрим команду:

Наш лексический анализатор должен разделить эту строку на следующий список токенов:

Напишем код компилятора. Для начала создадим файл lexer.py, в программном коде которого будут определяться токены. Для создания лексического анализатора воспользуемся классом LexerGenerator библиотеки RPLY.

Создадим основной файл программы main.py. В этом файле мы впоследствии объединим функционал трех компонентов компилятора. Для начала импортируем созданный нами класс Lexer и определим токены для нашей однострочной программы:

При запуске main.py мы увидим на выходе вышеописанные токены. Вы можете изменить названия своих токенов, но для простоты согласования с функциями парсера их лучше оставить как есть.

2. Синтаксический анализатор

Второй компонент компилятора – синтаксический анализатор (он же парсер). Его роль – синтаксический анализ текста программы. Данный компонент принимает список токенов на входе и создает на выходе абстрактное синтаксическое дерево (АСД). Эта концепция более трудна, чем идея списка токенов, поэтому мы настоятельно рекомендуем хотя бы по приведенным выше ссылкам изучить принципы работы парсеров и синтаксических деревьев.


Чтобы воплотить в жизнь синтаксический анализатор, будем использовать структуру, созданную на этапе РБНФ. К счастью, анализатор RPLY использует формат, схожий с РБНФ. Самое сложное – присоединить синтаксический анализатор к АСД, но когда вы поймете идею, это действие станет действительно механическим.

Во-первых, создадим файл ast.py. Он будет содержать все классы, которые могут быть вызваны парсером, и создавать АСД.

Во-вторых, нам необходимо создать сам анализатор. Для этого в новом файле parser.py аналогично лексеру используем класс ParserGenerator из библиотеки RPLY:

Наконец, обновляем файл main.py, чтобы объединить возможности синтаксического и лексического анализаторов:

Теперь при запуске main.py мы получим значение 6. и оно действительно соответствует нашей однострочной программе "print(4 + 4 – 2);".

Таким образом, при помощи двух этих компонентов мы создали работающий компилятор, интерпретирующий язык TOY. Однако компилятор по-прежнему не создает исполняемый машинный код и не оптимизирован. Для этого мы перейдем к самой сложной части руководства – генерации кода с помощью LLVM.

3. Генератор кода

Третья и последняя часть компилятора – это генератор кода. Его роль заключается в том, чтобы преобразовывать АСД в машинный код или промежуточное представление. В нашем случае будет происходить преобразование АСД в промежуточное представление LLVM (LLVM IR).

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

Чтобы начать, создадим файл codegen.py, содержащий класс CodeGen. Этот класс отвечает за настройку LLVM и создание/сохранение IR-кода. В нем мы также объявим функцию печати.

Теперь обновим основной файл main.py, чтобы вызывать методы CodeGen:

Как вы можете видеть, для того, чтобы обработка происходила классическим образом, входная программа была вынесена в отдельный файл input.toy. Это уже больше похоже на классический компилятор. Файл input.toy содержит все ту же однострочную программу:

Наконец, самое важное. Мы должны изменить файл ast.py, чтобы получать эти объекты и создавать LLMV АСД, используя методы из библиотеки LLVMlite:

После изменений компилятор готов к преобразованию программы на языке TOY в файл промежуточного представления LLVM output.ll. Далее используем LLC для создания файла объекта output.o и GCC для получения конечного исполняемого файла:

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

Мы надеемся, что после прохождения этого руководства вы разобрались в общих чертах в концепции РБНФ и трех основных составляющих компилятора. Благодаря этим знаниям вы можете создать свой язык программирования и написать оптимизированный компилятор при помощи Python. Мы призываем вас не останавливаться на достигнутом и добавить в свой язык и компилятор другие важные составляющие:

Читайте также: