LINUX.ORG.RU

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


0

0

Привет. Нужны доки как сделать свой интерпретатор. Идеи есть, но, думаю, что всё предумано до меня.

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

★★★★★

Ахо, Сети, Ульман. "Компиляторы" она же Dragon Book.

Забей. Почитай SICP и юзай Scheme. Благо реализаций вагон и тележка.

Macil ★★★★★
()

Положи рубанок в сторону и возьми Lua.

LamerOk ★★★★★
()

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

Конвертируешь текст лиспом в лисп, натравливаешь на него встроенный в лисп компилятор и вызываешь как функцию. Я несколько месяцев назад влез тут в спор, пришлось писать.

Absurd ★★★
()

посмотри на первую статью во втором номере журнала практика функционального программирования - http://fprog.ru/2009/issue2/

какие именно ограничения? почему бы не взять ECL или guile или lua?

ott ★★★★★
()
Ответ на: комментарий от Absurd

угу, лиспобразные языки в этом смысле очень легки в реализации

ott ★★★★★
()

http://compilers.iecc.com/crenshaw/

Но лучше всё-таки не нужно. Возьми готовый. Это не так просто, как кажется. (Обычно продолжает казаться до тех пор, пока не будет написана первая рабочая версия. Потом сразу разочарования по поводу скорости/памяти/гибкости/etc)

bvvv
()
Ответ на: комментарий от ott

>почему бы не взять ECL или guile или lua?

или Tcl, или REBOL. почему о них всё время забывают?

jtootf ★★★★★
()
Ответ на: комментарий от mannaz

что-то у кернигана или ричи было по этому поводу

kto_tama ★★★★★
()

Всем спасибо, направление нащупано.

Пока пишу на питоне интерпретатор байт-кода. Весьма занимательно Даже если конечной цели не достигну, всё равно интересно. Тут очень сильно пригодилось знание устройства питона(к сожалению, его парсер пока не осилил).

Вот такое уже работает :).

instructions = ('assign', "x", 4, 'assign', 'y', 1, 'end')

Да, можно взять готовое решение, но хочется самому попробовать.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от Absurd

Или конвертируешь текст С в С, натравливаешь на него gcc и вызываешь как функцию. Или конвертируешь текст в Пайтон, ну дальше вы поняли. Почему, собственно, лисп?

Legioner ★★★★★
()
Ответ на: комментарий от anonymous

Керниган & Пайк
Unix - универсальная среда программирования
8-я глава - создание интерпретатора команд

kto_tama ★★★★★
()

Нахрена нужна Книга Дракона для простого интерпретатора? Наверняка есть специальная литература именно по интерпретаторам.

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

tailgunner ★★★★★
()

>Велосипед нужен в силу больших ограничений по скорости и памяти

Тогда - нет ничего лучше Форта :)

KRoN73 ★★★★★
()
Ответ на: комментарий от Legioner

>Или конвертируешь текст С в С, натравливаешь на него gcc и вызываешь как функцию.

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

Absurd ★★★
()
Ответ на: комментарий от Absurd

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

Legioner ★★★★★
()
Ответ на: комментарий от true_admin

>в силу больших ограничений по скорости и памяти
>Пока пишу на питоне интерпретатор байт-кода


что-то тут не вяжется. или ты так, для self-test?

k0l0b0k ★★
()
Ответ на: комментарий от Legioner

>Если топикстартер хочет лиспоподобный язык - то да.

Паскаль, например, это совсем не лисп, но оттранслировать можно вполне однозначно - вместо procedure и function defun, вместо var let, вместо := setf вместо for loop итп в том же роде.

Absurd ★★★
()
Ответ на: комментарий от Legioner

+ записи, File of, указатели, with, вообще нормальные сообщения об ошибках. Для реализации придётся писать больше чем что то тривиальное (если речь идёт о чём то пригодном для практического использования).

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

>А ошибки типизирования как ловить во время компиляции?

Наверно надо сделать замену всем операторам чтобы они выводили типы возвращаемого значения на основании операндов и строить AST-дерево используя эти операторы. Потом делать eval на каждое выражение и получать тип.

Absurd ★★★
()
Ответ на: комментарий от k0l0b0k

> что-то тут не вяжется. или ты так, для self-test?

да, макет приложения. Я в последнее время часто так делаю. Хотя бы потому что в процессе разработки многое меняется и передалть питоновскую прогу проще чем на сях. А потом, когда получен готовый результат и API со структурами данных стабилизировались можно перегонять в C.

true_admin ★★★★★
() автор топика

на базе GCC, см. GCC-Frontend-HOWTO: http://tldp.org/HOWTO/GCC-Frontend-HOWTO.html -- описано, как с помощью Bison/flex сделать язык-калькулятор в качестве фронтенда к GCC

на базе ANTLR, см. http://tech.puredanger.com/2007/01/13/implementing-a-scripting-language-with-... http://www.bitwisemag.com/2/DLR-Build-Your-Own-Language или учебные примеры http://www.antlr.org/wiki/display/CS652/CS652+Home http://www.antlr.org/wiki/display/ANTLR3/Example

можно посмотреть примеры языков в разделе Documentation

на базе LLVM, см. http://llvm.org/pubs/2009-05-21-Thesis-Barrett-3c.pdf -- на Python студентом написан фронтенд своего бейсик-подобного языка. LALR-парсер, пример недоделанный (производительность получилась слабая), но пример написан студентом за пару месяцев. Можно взять например Python фронтенд к ANTLR и по аналогии сделать свой компилятор через LLVM-биндинги.

Примеры на лиспе http://www.lispforum.com/viewtopic.php?f=2&t=149&start=0 http://www.cliki.net/LanguagesImplementedInLisp -- здесь интересны CLPython и ejacs

Примеры на хаскелле приводить не буду. Есть тот же бейсик by Lennart Augustsson http://augustss.blogspot.com/2009/02/is-haskell-fast-lets-do-simple.html (через LLVM биндинги)

anonymous
()

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

Тебе нужен готовый язык вроде Lua или ты хочешь потренироваться написать свой интерпретатор?

anonymous
()
Ответ на: комментарий от true_admin

см. в эту тему, OMeta/PyMeta : http://washort.twistedmatrix.com/2008/03/pymeta-how-and-why.html

см. YML: http://fdik.org/yml/index#motivation -- там PyPEG http://fdik.org/pyPEG/

http://pysch.sourceforge.net/ast.html http://www.mare.ee/indrek/sablecc/ -- см. "Technology" -- как раскрутили новый язык через парсер+дамп AST в XML + XSLT трансформации полученного XML

anonymous
()
Ответ на: комментарий от KRoN73

>Тогда - нет ничего лучше Форта :)

двачую за форт. Можно взять, например, Factor: http://factor-language.blogspot.com/2009/09/survey-of-domain-specific-languag... и накрутить чего-то вокруг его PEG парсера.

Можно написать Metacirrular interpreter на форте, см. пример в конце http://c2.com/cgi/wiki?MetaCircularEvaluator

anonymous
()
Ответ на: комментарий от k0l0b0k

по времени там самый трудоёмкий этап: "перегнать застабилизированное питонье API в Си". Этот этап можно автоматизировать, если взять язык не совсем питон, но что-то похожее на Nimrod(в Си), Geanie в Vala(и в Си), Deelight в D. Для D можно посмотреть CeleriD и PyD, генерацию биндингов средствами метапрогаммирования в D. В презентации CeleriD было сравнение трудоёмкости других вариантов Python+CPython, Pyrex, и т.п.

anonymous
()
Ответ на: комментарий от k0l0b0k

> а по времени как, не перегибает?

меня нет ибо я тот ещё C-программист. Лучше 10 прог на питоне напишу чем одну на C-ях которую вдоль и поперёк с valgrind и gdb дебажить :).

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

А ещё бывает что напишешь такой макет а потом понимаешь что и переписывать незачем :).

true_admin ★★★★★
() автор топика
Ответ на: комментарий от Legioner

> Если нет - придётся писать стандартный набор для лексического, синтаксического анализа. И тут у лиспа преимуществ никаких перед другими ЯП я не вижу.

ну вот возьмём например META http://home.pipeline.com/~hbaker1/Prag-Parse.html http://portal.acm.org/citation.cfm?id=1093417 http://www.cliki.net/meta http://www.cb1.com/~john/thesis/thesis.html

и его более позднее развитие в сторону OMeta: http://subvert-the-dominant-paradigm.net/blog/?p=23 http://subvert-the-dominant-paradigm.net/blog/?p=38 (или вообще META 2 http://en.wikipedia.org/wiki/META_II и PEG-парсер, http://subvert-the-dominant-paradigm.net/blog/?p=17 )

Bootstrapping: http://subvert-the-dominant-paradigm.net/blog/?p=32 -- довольно хорошо описывает, какие преимущества у лиспа.

Собственно, не то чтобы именно лисп, сам Metacirrullar подход. Парсер ставит в соответствие грамматике семантические действия, шаблоны, заполнение которых выдаёт готовый код в целевом языке (хост-языке для OMeta).

Если сравнить реализации OMeta: исходную на смоллтоке, на лиспе, на C#, мы увидим, что у первых двух наиболее прозрачный синтаксис, на C# -- постоянные шаблоны и кастинги, для обслуживания статической типизации. Код на лиспе ближе всего к грамматике исходного языка. Какие свойства лиспа для этого используются? Нужен язык шаблонов? - берём Sexpr шаблона, если элемент список, вычисляем его, подставляем значение. Нужна типизация для семантических действий? => используем multiple dispatch или динамическую типизацию. Нужен компилятор, а не интерпретатор? => делаем функции "платформы OMeta" макросами, генерируем код на лиспе, компилируем.

Если посмотреть на "Running OMeta Parsers Backwards for Source-to-Source Translation" http://www.vpri.org/pdf/m2008001_parseback.pdf -- там неявно используется homoiconicity свойства смоллтока (или лиспа, неважно). Для заполнения шаблона, для трансформаций AST в нужный "общий" вид, для перевода токенов в правила грамматики, правил в семантические действия, действий в интерпретируемый код на хост-языке.

Компилятор и интерпретатор разбираемого языка выглядят однотипно. Вся разница в том, когда вызывается "код платформы", который транслирует исходный язык в целевой. Можно описать грамматику на OMeta, прогнать под интерпретатором, исполнить; потом сгенерировать выходной текст и откомпилировать. Можно вынести платформу в макросы и сразу компилировать. Можно перейти от прототипа-интерпретатора к откомпилированному варианту в полдвижения. Можно сразу протестировать интерпретатор или компилятор.

Как этого добиться без homoiconicity и динамической типизации? Ага, шаблонами со стат. типизацией в духе OMeta#. Но теряем весь спектр интерактивности, тестирования "по-живому", прозрачности кода.

Хотя у OMeta своя узкая ниша -- парсер как интерпретатор, и производительность PEG не ахти. Не проблема, пишем на OMeta грамматику OMeta, ANTLR и применяем "running parsers backwards" из OMeta в ANTLR.

anonymous
()
Ответ на: комментарий от anonymous

> Опиши, какой язык и зачем требуется. Почему именно интерпретатор, какие "ограничения по скорости и памяти", что он должен уметь.

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

Соотв. есть ограничения по скорости.

Вообще, я понял что прямо сейчас не готов этим заняться. Думаю, вернусь к теме когда два других проекта доделаю. А так тупо на всё времени нет (:.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от Legioner

>А ошибки типизирования как ловить во время компиляции?

типизирования чего? вроде проверки типов в исходной программе на паскале? как обычно, семантическим анализатором построенного AST паскалевской программы. Если получаем некорректное по типам дерево -- ругаемся и вываливаемся.
Зачем от интерпретатора/компилятора здесь статическая типизация? Дерево проверить на корректность можно в любом случае. Всё равно, если уж на то пошло, нужна более сильная типизация -- корректность дерева, а не корректность интерпретатора/компилятора при обходе дерева.

Если ошибки семантического анализатора проигнорировать -- получим питон, а не паскаль :)

anonymous
()
Ответ на: комментарий от true_admin

то есть, ты хочешь генерировать конфиги nginx из какого-то DSL или наоборот, встроить в nginx язык такого DSL более кошерных конфигов?

anonymous
()
Ответ на: комментарий от anonymous

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

true_admin ★★★★★
() автор топика
Ответ на: комментарий от Legioner

>И тут у лиспа преимуществ никаких перед другими ЯП я не вижу. Хоть на джаве пиши

исчо в тему: http://web.archive.org/web/20050307111232/http://www.functionalobjects.com/re...

-- про написание компилятора IDL на Java и на Dylan (тот же common lisp с алголоподобным синтаксисом, в основном)

anonymous
()
Ответ на: комментарий от anonymous

>Видел http://lambda-the-ultimate.org/node/3281?

thanks, по ссылке оттуда: http://www.nongnu.org/l-lang/manual/documentation.html#L-in-brief

>L is: >It is an extensible programming language : even the syntax is modifiable at run-time. >A compiled language with a C-like syntax, and Lisp-like macros.

<кастую в тред den73. Он вроде искал нечто подобное>

anonymous
()
Ответ на: комментарий от anonymous

>L is:

>It is an extensible programming language : even the syntax is modifiable at run-time. >A compiled language with a C-like syntax, and Lisp-like macros.

Последний коммит - 2 года назад.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

версия L-0.1 тоже доставляет. Не суть, главный вопрос -- решает ли оно поставленные den73 задачи с его Т.З.

А то я могу ещё древнее ссылок накопать, например goo http://en.wikipedia.org/wiki/Goo_(programming_language) http://people.csail.mit.edu/jrb/goo/ GUI: SamurUI http://radio.weblogs.com/0102385/2003/02/06.html http://web.archive.org/web/20050101043624/http://www.ai.mit.edu/~jrb/goo/wiki... http://web.archive.org/web/20030702125352/www.ai.mit.edu/~jrb/goo/wiki/index.... -- оно вообще версия 0.155 2005-го года.

Goo вообще раритет, судя по скудной доке и заглохшему мейллисту, окаменевшее гавно мамонта, и сейчас представляет в основном, исторический интерес. Правда, если покапаться в отложениях, Dylan-то ещё древнее. Берём OpenDylan на 90Мб, ставим, сравниваем. Собираем goo в пару мегабайт -- и опа, почти тот же Dylan.

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

anonymous
()
Ответ на: комментарий от anonymous

Хух, сколько всего нового для себя открыл... =)

MELT очень привлёк. Несколько отталкивает его состояние: это даже не альфа - что-то наколенное, полученное при стремлении к иным целям... Но очень заинтересовало. Надо попробовать

Nimrod тоже впечатляет. К релизу обещают треды, прочие вкусности и доделку макр (сейчас дока по ним пестрит "unimplemented"). И, по сравнению с MELT, очень привлекает своей "законченностью" - готовый продукт.

Ладно, будем "посмотреть". Спасибо за интересные ссылки =)

yyk ★★★★★
()

А что тут думать ? Берешь lex + yacc и вперед :)

aldayneko
()
Ответ на: комментарий от yyk

При ближайшем рассмотрении обе кандидатуры "ушли в топку" - слишком велика плата "за то, что не используешь".

Нет в жизни счастья... =)

yyk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.