Как делаются скриптовые языки программирования?

Чисто из любопытства возник вопрос ,как делаются скриптовые языки программирования? Например php ,то что он на C написано это все знают, но как? Я чисто для себя хочу написать свой язык с всего лишь пару функциями, но со своим компилятором. И можно ли это реализовать на C# ? :)
  • Вопрос задан
  • 2481 просмотр
Пригласить эксперта
Ответы на вопрос 7
Короткий ответ: читаем книгу дракона. Есть и более навороченная литература, но начинают все с этой книги (нам по ней читали в универе курс трансляции языков).

Длинный ответ: ваш транслятор принимает на вход последовательность символов (допустим, UTF-8 текст), "понимает" ее в соответствии со спецификацией вашего языка, и выплевывает в качестве вывода инструкции на другом языке (в виде текстового файла или файла спец. формата). Этим "друим языком" может быть язык ассемблера какой-то железной платформы (x86_64, ARM, SPARC), и результирующим файлом будет бинарник под указанную архитектуру (точнее - объектный модуль, бинарник потом будет собран линковщиком) - так компилятся, например, C/C++. "Другим языком" может быть язык виртуальной машины (LLVM/байткод Java/MSIL) - так компилятся С/C++ (если через LLVM), Java, Scala, C#, F#, VB. "Другим языком" может быть и более высокоуровневый язык - часто, чтобы не париться на начальных этапах развития языка генерацией машинного кода, делают транслятор, который генерит код на Си, и этот код на Си уже компилят известным компилятором в бинарник. Или к примеру, CoffeeScript/TypeScript транслируются в JavaScript, т.к. веб-браузеры кроме джаваскрипта исполнять пока ничего не умеют.

Конечно же, вы можете написать интерпретатор, а не компилятор - тогда ваша программа будет сразу же исполнять инструкции на вашем языке, не генерируя какой-либо выходной файл. Так поступают довольно много систем, например Node.js. Python делает также, если отключить генерацию pyc-файлов (поправьте меня, если я ошибаюсь).

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

Т.к. в задачах разбора входного потока (parsing) уже набито очень много шишек, и люди посвятили свои жизни и научные карьеры изучению этого вопроса, то сделано и немало инструментов для помощи в разработке компилятора. Как правило, такие инструменты дают возможность описать грамматику вашего языка на некоем специализированном синтаксисе (вроде BNF), а потом по этому описанию генерят вам код лексера и парсера на удобном для вас языке (это модули, которые выполнят первичный разбор входного потока на вашем языке на токены, и построят абстрактное синтаксическое дерево (AST)). А вы уже дописываете к ним основную часть вашего компилятора. Как пример, при написании компиляторов на языке Си часто используют flex в связке с yacc/bison. Есть более комлексные пакеты, позволяющие генерить код парсеров на различных языках - ANTLR, GOLD. А можно и самому написать лексер и парсер, особенно если вы уже сделали первую версию компилятора и переписываете его на вашем же языке).
Ответ написан
Комментировать
tsarevfs
@tsarevfs
C++ developer
Скриптовыми обычно называют языки исполняющиеся интерпретатором. Компилятор преобразует код программы в машинные инструкции, которые могут исполняться самостоятельно, и это намного сложнее.
Начните с чего-то очень простого. Например с программы, которая читает по одной строчке с инструкциями и выводит результат. Пусть в строчке сначала будет всего одна команда. Например:
input: add 2 3
output: 5
Потом попробуйте на основе этого написать калькулятор для выражений. Поиск того, как это сделать можно начать отсюда.
Когда это будет сделано, можно будет двигаться дальше.
Ответ написан
Комментировать
opium
@opium
Просто люблю качественно работать
В универе рассказывают курс теория языков программирования чтобы такие вопросы не задавали
Ответ написан
Первый комментатор уже все сказал и сложно что-то добавить, но я бы советовал посмотреть на forth или другие стековые языки.
Стековая машина пишется очень быстро, буквально за пол дня. Если тебе действительно нужно пара функций, то этот вариант может подойти.
Ответ написан
Комментировать
В учебных целях можно воспользоваться генераторами компиляторов, такими как Coco/R (читать документацию!)
В кратце: создаёшь описание грамматики языка, а генератор создаёт за тебя файлы сканера и парсера, которые нужно скомпилировать для получения исполняемого файла компилятора.
На сайте www.ssw.uni-linz.ac.at/Research/Projects/Coco есть примеры для разных ЯП.
Ответ написан
Комментировать
@dponyatov
Для написания интерпретатора очень важно понять самый главный принцип: интерпретация структур данных

Программа представляется в виде структуры данных, чаще всего это дерево (или граф) объектов, в каждом узле находится объект, представляющий различные элементы языка: константа, функция, цикл и т.п.
Каждый элемент обязательно должен иметь возможность содержать в себе
(а) элементы адресуемые по имени (ассоцифтивный массив) и
(б) вложенные элементы причем в контролируемом порядке (массив или список).
Интерпретатор бегает по дереву/графу программы, и выполняет действия через вызовы методом объектов.
Например у class Operator -> Plus задается метод add() { return nest[0].add( nest[1] }
nest это список вложенных элементов (операнды)

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

кое-что есть здесь в глубокой преальфе (интерпретатор на питоне) https://github.com/ponyatov/hico/releases/latest
Ответ написан
Комментировать
A1ejandro
@A1ejandro
youtube блогер, ИТ-специалист
В свое время я разработал (еще на Досовском Паскале, хоть и с использованием ООП) собственный интерпретатор, специально для системы сопряжения PC-network с Mainframe (реализовывалось тогда всё это еще и через собственноручно сделанный гейт сети Иола в связке с Novell - при чем разработчики Иола утверждали что такой гейт вообще невозможно создать). Так вот система моя занималась скоростным вводом/набором данных с бумажных носителей и передачей всего этого на Mainframe (IBM) в нужном ему формате. Короче у меня была задача сделать систему с "визуальным проектированием макетов ввода данных операторами". Реализовать получилось, макет было достаточно "нарисовать" в текстовом файле с указанием типов вводимых данных, и он сразу "оживал", в него сразу можно было набирать данные. При всем этом скорость ввода данных по стравнению с какой то старой перфокарточной системой повысилась в разы. Интересный был и вполне себе практический опыт разработки, можно сказать "скриптового языка" =)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы