[написание компиляторов] надо написать компилятор Scheme на нём же
Собери мысли в узду, пожалуйста. Совсем ведь ничего не понятно чего ты хочешь!
например, довольно просто написать транслятор с паскаля в псевдоавтокод из десятка команд всего. и написать виртуальную машину (VM которая этот псевдоавтокод выполняет. плюс для удобства дописать байндинги на некоторые системные вызовы, например файловый ввод-вывод (включая консоль).
для паскаля есть готовые - смотри FastScript, PascalScript например.
и да, насколько мне помнится, для схемы пишут интерпретаторы
компилятор - это сложная штука. проще всего написать транслятор в некоторое "внутреннее представление" и к этому внутреннему представлению написать виртуальную машину.Или воспользоваться готовой виртуальной машиной, например LLVM.
еще раз надо написать компилятор схемы на схеме. такая вот проблема вобщем.
p.s. компиляторов я никогда не писал, но хотябы хоть какойннить ресурс посоветуйте как писать компиляторы на ассемблере.
Пример готового кода - компиляторов и интерпретаторов лиспа и еще чего-то - в коде к книге Норвига "AIMA": http://aima.cs.berkeley.edu/code.html
соответственно, код тоже на Лиспе, но переписать на Схеме не сложно.
ассемблер и другие суровости не обязателен даже для оптимизирующего компилятора, а реализация основных функций лиспа на лиспе весит около 200 строчек кода
Разумеется, без стандартных библиотек.
Только нафига он тебе?
Только нафига он тебе?да там одного парня отчислили на одном сайте, у него было задание написать компилятор схемы на схеме. я в этих делах и правда не ездец, но излил вопрос как и что можно было бы парню сделать чтобы восстановился. я обычный физег дятел. взвешиваю гирьки на весах. а потом разгоняю их до сврехсветвовой скорости и после смотрю что будет.
компиляторов не писал однако.
отчислили на одном сайтеВ каком смысле "отчислили на сайте"? Может из университета?
наркошапоходу чувака накрыло
этот чтоле?
The 90 Minute Scheme to C compiler - Marc Feeley
http://www.iro.umontreal.ca/%7Eboucherd/mslug/meetings/20041...
еще раз надо написать компилятор схемы на схеме. такая вот проблема вобщем.Чушь какая-то. Не трогай Схему своими грязными руками.
Не трогай Схему своими грязными руками.сх эмо!
Наглая ложь.
---
"Narrowness of experience leads to narrowness of imagination."
Какой-нибудь форт или елисп, естественно, простые.
Если же хочется статический (то бишь лексический) скопинг, статическую типизацию (в том числе используемую для оптимизации типовыведение к ней, кучу важных мелочей типа модулей/пакетов и value types, GC (свой, а не потыренный у метаэвалюатора! нормальный синтаксис без поддержку мультитрединга, итдитп, то задача становится гораздо менее тривиальной.
типовыведение к нейдовольно быстро. Проблема только возникает с псевдостатической типизацей вроде принятой в цешарпе-джабке. Тогда да, еботня обеспечена.
В этом и смысл.
Только и вопрос стоял изначально про "что-нибудь,"
даже "схема" приползла не потому что этого так желает автор,
а потому что последний слышал, что "схему" просто сделать.
Про то, что эта схема потребует хотя бы сборку мусора, автор,
разумеется, не узнал и не озаботился узнаванием возможности
таких неожиданностей.
> задача становится гораздо менее тривиальной.
---
"Narrowness of experience leads to narrowness of imagination."
P.S. То, что "паскаль" тоже вполне ничего язык программирования,
но сделать компилятор значительно проще, чем схему, так никто и
не вспомнил.
P.P.S "нормальный синтаксис без "
Это чем это тебе наши скобки не синтаксис?
Тем более, что "нормальный синтаксис" как раз вторичен,
особенно если вспомнить про Standard Lisp и Dylan.
Про типовыведение и прочую ненужную ерунду можно развести
отдельную воду.
@контра: я как-то не очень понял, что всё-таки является наглой ложью, что компилятор - сложная штука, или что схему просто сделать.
Компилятор паскаля сделать сложно. Там много нетривиального синтаксиса, много откровенно ебанутого синтаксиса (лексемы для флоатов конфликтуют с range literals так что даже вооружившись какой-нибудь чужой парсинг лайбрари потрахаться придётся. Ну, плюс структуры всякие, указатели... Не, схема с тормозным наколенным GC точно проще.
Компилятор брейнфака сделать просто. Тоже язык, между прочим.
> Это чем это тебе наши скобки не синтаксис?
Слово "нормальный" ключевое.
> Тем более, что "нормальный синтаксис" как раз вторичен,
> особенно если вспомнить про Standard Lisp и Dylan.
Вот именно поэтому...
> типовыведение и прочую ненужную ерунду
ditto
лексемы для флоатов конфликтуют с range literalsто есть, необходимость отличать одну и две подряд идущие точки, имеющие к тому-же непересекающиеся области применения уже стала нетривиальной проблемой?
> что компилятор - сложная штука
Ровно что написано: что компилятор сложная штука.
Компилятор можно сделать как угодно простым и как угодно сложным,
это зависит от языка и от твоих личных заморочек насчёт автокода,
связывания, оптимизации и т. д.
> Не, схема с тормозным наколенным GC точно проще.
Так тоже можно.
Ещё можно выкинуть из синтаксиса балансировку скобок и сборку мусора.
>> Тем более, что "нормальный синтаксис" как раз вторичен,
>> особенно если вспомнить про Standard Lisp и Dylan.
> Вот именно поэтому...
Я не считаю синтаксис в традициях SPAD-Occam-Dylan-Python
очень уж удобным.
Что касается R-Lisp... Пока не использовал его на деле,
воздержусь от суждений.
---
"You've got TECO. What more do you want?"
> то есть, необходимость отличать одну и две подряд идущие точки,
> имеющие к тому-же непересекающиеся области применения уже
> стала нетривиальной проблемой?
В переводе на русский, "это плохо потому, что плохо делится на
сканнер и парсер." То, что сканнер не обязательно lex и его
можно не выделять вообще, насильнику-униксоеду не очевидно.
---
...Я работаю антинаучным аферистом...
развей мысль, если не затруднит.типовыведение в ситуации когда экземпляр может иметь несколько типов становится гораздо более сложным и большим (по коду) чем в ситуации строгой статической типизации: один экземпляр - один тип.
можно не выделять вообще, насильнику-униксоеду не очевидно.
---
ололо, ну ладно, насильник-униксоед так насильник униксоед =)
Сканнер практически всегда на регексах, лекс или не лекс. Потому что это просто и удобно. Я в курсе того, что у некоторых людей есть идеи про использование бнф-лайк до самого низа, типа парсек и всё тут, я сомневаюсь, что первопроходец, реализующий грамматику паскаля таким образом, может считаться человеком, выбравшим простоту, ггг.
Так вот, проблема в том, что "3." и ".3" являются корректными записями флоатов, поэтому наивное описание лексики замечательно бьёт "3..3" именно таким образом. Ибо жадное (и должно быть жадным, вощемта). Можно было бы побороться лукахедом, но я не уверен, что все движки парсеров их массово поддерживают, и уж точно задолбаешься его делать руками, если хочется совсем чистой-велосипедной имплементации компилятора.
Поэтому приходится завести новую лексему "инт с двумя точками", пройтись за лексером и позаменять все её вхождения на "инт", "две точки" (потому что рейнджи бывают не только интовые, так что их точно должен обрабатывать синтаксический парсер).
Это, разумеется, совсем не ужас-ужас-ужас. Но таких мерзких сюрпризов и особых случаев в паскале довольно много, так что мысли вроде "да чо, простой язык же, за выходные можно что-то работающее наваять, если умеючи" наивны!
@emacs: я не понимаю, ты какой язык имеешь в виду, можешь сказать конкретно?
> Потому что это просто и удобно.
Я, напротив, считаю, что это не настолько просто и удобно, как
кажется на первый взгляд. Хотя бы из-за того, что оно не просекает
некоторые простые случаи, встречающиеся на деле, или, по крайней
мере, их не так просто учесть.
> Я в курсе того, что у некоторых людей есть идеи про использование
> бнф-лайк до самого низа, типа парсек и всё тут, я сомневаюсь, что
> первопроходец, реализующий грамматику паскаля таким образом, может
> считаться человеком, выбравшим простоту, ггг.
Тогда ты в теме взаимоотношений пана Никлауса и предиктивных парсеров.
> Так вот, проблема в том, что "3." и ".3" являются корректными
> записями флоатов,
В паскале нет "флоатов," в паскале "реалы."
> поэтому наивное описание лексики замечательно бьёт "3..3"
> именно таким образом. Ибо жадное (и должно быть жадным,
> вощемта). Можно было бы побороться лукахедом, но я не уверен,
> что все движки парсеров их массово поддерживают, и уж точно
> задолбаешься его делать руками, если хочется совсем
> чистой-велосипедной имплементации компилятора.
Ты чуть выше писал про медленный сборщик мусора, а написать
медленный, но более удобрый разбор не настолько сложно (тем
более, что всё уже украдено "3..3" не может быть разобрано
как два числа просто потому, что грамматика паскаля никак не
допускает два подряд идущих числа. Так что GLR отсечёт такую
возможность. Итого, немного подумав, ты лишаешь себя счастья
иметь запарки с набившим оскомину LALR.
> Поэтому приходится завести новую лексему "инт с двумя точками",
> пройтись за лексером и позаменять все её вхождения на "инт",
> "две точки" (потому что рейнджи бывают не только интовые, так
> что их точно должен обрабатывать синтаксический парсер).
И "3...3" ты разберёшь не так, как тебе подсказывает жадность.
Заметь, что GLR его сделает как обычно, потому что будет вести
два потока: "целое, две точки, дробь, дробная часть" и "целая
часть, дробь, две точки, целое",--- с обычным конфликтом
"сдвиг-свёртка," который известно как решать.
> "да чо, простой язык же, за выходные можно что-то работающее
> наваять, если умеючи" наивны!
Смотря какой длины выходные. По нынешним временам можно и наваять.
(Опять же, ваять можно что-нибудь паскалеподобное, не обязательно
сам паскаль, как это описано стандартом.)
---
...Я работаю антинаучным аферистом...
У меня есть глубокое убеждение, что подобные случаи в подавляющем большинстве случаев свидетельствуют о фиговости синтаксиса. В смысле что регексы довольно хорошо приближают то, как парсит код программист, поэтому корреляция между мандфаками и парсингфаками положительна и довольно велика. Например в данном случае программист, конечно, распарсит 3..3 легко, но только за счёт того, что 3.,.3 вызовет у него истерический хохот.
> В паскале нет "флоатов," в паскале "реалы."
Это флоаты. Это не 32битные и не 64битные флоаты, но флоаты неверзелесс.
> медленный, но более удобрый разбор не настолько сложно
Я никогда не писал GLR, ты действительно уверен, что он пишется достаточно легко? Ведь насколько я понимаю, грамматику паскаля можно вообще чуть ли не рекурсивно топ-даун парсить, в паре мест разве что может понадобится какую-нибудь военную хитрость применить.
> "3...3"
К счастью, я не хочу разбирать это, я хочу падать по ошибке. Я и глазами это разбирать не хочу, собственно, это и определяет.
> подавляющем большинстве случаев свидетельствуют о фиговости
> синтаксиса. В смысле что регексы довольно хорошо приближают
> то, как парсит код программист
"Сегодня в колбасе потребности нет."
Я не верю в это утверждение.
>> В паскале нет "флоатов," в паскале "реалы."
> Это флоаты. Это не 32битные и не 64битные флоаты, но флоаты
> неверзелесс.
Настоящий насильник, да. Даже в Языке Программирования они
называются реалами.
>> медленный, но более удобрый разбор не настолько сложно
> Я никогда не писал GLR, ты действительно уверен, что он
> пишется достаточно легко?
Ты перебор в ширину писал? В общем-то это обычные сдвиги и
свёртки, только если есть два возможных варианта продолжения,
рабочий стек разветвляется и дальше каждый входящий символ
поступает на обе головы, сдохшая ветка убивается. Я понимаю,
что там где-нибудь может быть засада, но особых трудностей
пока не вижу. Ты видишь?
> Ведь насколько я понимаю, грамматику паскаля можно вообще
> чуть ли не рекурсивно топ-даун парсить, в паре мест разве что
> может понадобится какую-нибудь военную хитрость применить.
"Чуть ли." Значит ты не в теме взамиоотношений пана Никлауса и
предиктивных парсеров. Вкратце, пан Никлаус считает их ересью,
а халяльным парсером объявляет рекурсивный десант.
---
...Я работаю антинаучным аферистом...
Настоящий насильник, да. Даже в Языке Программирования онизато по IEEE стандарту они называются float-ами.
называются реалами.
> Заметь, что GLR его сделает как обычно, потому что будет вести
> два потока: "целое, две точки, дробь, дробная часть" и "целая
> часть, дробь, две точки, целое",--- с обычным конфликтом
> "сдвиг-свёртка," который известно как решать.
Тут ошибка. Язык неоднозначен, так что придётся вводить
дополнительные правила. Но если правильно упорядочивать,
то жадность достигается. Заодно достигается определение
неоднозначности, его можно будет как-то диагностировать.
---
"Утверждаю, что с научной точки зрения, главное в профессии вора,
как и в профессии святого, конечно, это вовремя скрыться."
Регулярные языки слишком сильно выделяются, чтобы в них не верить.
Заметь, я не утверждаю, что любая фигня, лексируемая регексами, легко разбирается программистом, я утверждаю необходимость.
Можешь попытаться привести пример, когда это не так.
> Настоящий насильник, да.
ггг, вот опять =) Нет, floating point values называются флоатами всегда, за исключением тех случаев, когда confused language designers пытались распространить своё confusion на юзеров, какбэ подразумевая, что их флоаты симулируют реалы с достаточной степенью точности. Разумеется, ничего, кроме further confusion из этого не могло произойти.
> но особых трудностей пока не вижу. Ты видишь?
В википедии написано, что без выделения коммонпрефиксов оно захлёбывается на практике.
> "Чуть ли."
Я про то, что преобразование грамматики например паскаля в доступный для рекурсивного опускания вид преображает её весьма сильно. Особенно если пытаться внести эти долбанутые но необходимые правила вида "секция объявления переменных идёт после секции объявления типов", ты, видимо, давно не видел паскаля, вот что. Это всё компьютер должен делать - строить таблички и прочее.
Сдаётся мне, что парсер сишки всё же проще написать. Благо, там есть куча невидимых даже на крайне внимательный взгляд вещей, вроде возможности писать "int i, *p, f(int *fp(int (*ff(intint ff2(int(int;", плюс возможность добавить в начало одно из трёх static, extern, typedef (!). Это валидный код, если ты сумеешь представить, как должен выглядеть парсер, то поразишься простоте и ортогональности. Всё необходимое для жизни получается в результате разбора по одному и тому же абстрактному дереву (которое является полностью валидной частью дерева для разбора выражений, declaration mimics use дико неспроста там семантическому парсеру остаётся записать получающиеся имена и типы в разные таблички. Ругаясь на недопустимые операции, если мы действительно одно и то же дерево используем для разбора выражений и определений.
Я правда считаю, что Си является одной из самых красивых вещей, когда-либо созданных человечеством, если определять красоту как отношение сложности вещи к сложности её underlying principles. Лиспы эти ваши, они снизу доверху просты, а тут вот такая красота. Так что я в какой-то мере всё-таки насильник, да!
Впрочем, уместно заметить, что эта дикая красота относится только к весьма ограниченному подмножеству C99, как должен выглядеть реальный компилятор можно понять, поглядев. Там и константные линкед-листы, и симулируемые named parameters, и вообще. Плюс действительно огромное количество дополнительных специальных случаев, периодически натыкаюсь на разные, но тут же забываю. int a[] = {2:3, 5:6};, типа такого.
> Регулярные языки слишком сильно выделяются, чтобы в них не верить.
> Заметь, я не утверждаю, что любая фигня, лексируемая регексами,
> легко разбирается программистом, я утверждаю необходимость.
> Можешь попытаться привести пример, когда это не так.
Парные скобки вложенностью до 100.000.000.000 тоже разбираются
регулярными выражениями. Как выглядит соответствующее выражение
на деле, программисты представляют очень хорошо.
>> Настоящий насильник, да.
> ггг, вот опять =) Нет, floating point values называются флоатами всегда,
> за исключением тех случаев, когда confused language designers пытались
> распространить своё confusion на юзеров, какбэ подразумевая, что их
> флоаты симулируют реалы с достаточной степенью точности.
> Разумеется, ничего, кроме further confusion из этого не могло произойти.
Не знаю, где ты встречал таких пользователей.
Программисты на Настоящем Языке обычно знают точность своих реалов.
Мало того, сокровенное знание, как надо писать, чтобы точность
не терялась передаётся из поколения в поколение, несмотря на то,
что тех компиляторов уже почти что нет.
>> но особых трудностей пока не вижу. Ты видишь?
> В википедии написано, что без выделения коммонпрефиксов оно
> захлёбывается на практике.
Не знаю. Я смотрел, как оно разбирало ограниченный ЕЯ.
Оно обещано кубичным. Ну, где-то так, наверное, оно и было.
Напомню, что ты сам заявлял, что для простоты можно написать
незамороченный сборщик мусора. Так что GLR здесь в тему.
>> "Чуть ли."
> Я про то, что преобразование грамматики например паскаля в
> доступный для рекурсивного опускания вид преображает её весьма
> сильно. Особенно если пытаться внести эти долбанутые но
> необходимые правила вида "секция объявления переменных идёт
> после секции объявления типов", ты, видимо, давно не видел
> паскаля, вот что. Это всё компьютер должен делать - строить
> таблички и прочее.
Насколько я помню, БНФ для паскаля помещается на пяти или шести
листах брошюрки. Может быть и ещё меньше. А вот преобразовать
эту БНФ к тому, что хочет LR, можно автомагически. Возможно,
с некоторой допиловкой, но не суть важно.
> Сдаётся мне, что парсер сишки всё же проще написать. Благо,
> там есть куча невидимых даже на крайне внимательный взгляд вещей,
> вроде возможности писать "int i, *p, f(int *fp(int (*ff(intint
> ff2(int(int;", плюс возможность добавить в начало одно из
> трёх static, extern, typedef (!). Это валидный код, если ты
> сумеешь представить, как должен выглядеть парсер, то
> поразишься простоте и ортогональности. Всё необходимое для
> жизни получается в результате разбора по одному и тому же
> абстрактному дереву (которое является полностью валидной
> частью дерева для разбора выражений, declaration mimics use
> дико неспроста там семантическому парсеру остаётся записать
> получающиеся имена и типы в разные таблички. Ругаясь на
> недопустимые операции, если мы действительно одно и то же
> дерево используем для разбора выражений и определений.
Я в это неверю хотя бы потому, что существует идиотизм с
приведением типов, sizeof и "long int" (например, "int f(long int)").
Кстати, несмотря на то, что возможно писать "int f(int, int);",
в объявлении надо уже писать "int f(int m, int n){...}",
ортогональность на грани фантастики. Объявления стиля K&R
делают жизнь ещё интереснее. Насчёт того, что можно писать
"ff2(int(int" сомневаюсь.
> Я правда считаю, что Си является одной из самых красивых вещей,
> когда-либо созданных человечеством, если определять красоту
> как отношение сложности вещи к сложности её underlying principles.
В это я не верю по другим причинам.
> Лиспы эти ваши, они снизу доверху просты, а тут вот такая красота.
> Так что я в какой-то мере всё-таки насильник, да!
Ты ещё не осознал всю красоту и мощь LOOP.
---
Escape-Meta-Alt-Control-Shift
Особенно если пытаться внести эти долбанутые но необходимые правила вида "секция объявления переменных идёт после секции объявления типов"Только если в секции определения переменных используются определяемые типы, но подобное можно найти в любом языке. Других ограничений для этих секций нет (разве только то, что они должны быть за пределами блоков с кодом).
Кстати, несмотря на то, что возможно писать "int f(int, int);",вроде, если m и n не используются, их имена не обязательно указывать
в объявлении надо уже писать "int f(int m, int n){...}",
>> Заметь, я не утверждаю, что любая фигня, лексируемая регексами,
>> легко разбирается программистом, я утверждаю необходимость.
> существует идиотизм с приведением типов
> что возможно писать "int f(int, int);",
> в объявлении надо уже писать "int f(int m, int n)"
Я вообще имел в виду, что особенности синтаксиса (включая невозможность двум и более айдентифаерам идти подряд кроме как в формальном параметре (long long и ко считаются одним айдентифаером позволяют вначале разобрать синтаксис приблизительно, зато одним и тем же куском кода разбирать и объявления, и имплементации, и вызовы функций, а потом уже в каждом конкретном случае проверить, что выполняются дополнительные условия.
Ну, я сам компилятора ещё не писал, но мне кажется, что так можно сделать.
> Насчёт того, что можно писать
> "ff2(int(int" сомневаюсь.
Это откуда ж ты пишешь, что скомпилить нечем? =)
> регулярными выражениями.
>> Заметь, я не утверждаю, что любая фигня, лексируемая регексами,
>> легко разбирается программистом, я утверждаю необходимость.
То есть, ты имеешь в виду, что если легко разбирается программистом,
то язык регулярен?
Ну, это вообще тривиально, потому что у программиста память не то,
чтобы короткая, а заметно короткая.
>> существует идиотизм с приведением типов
>> что возможно писать "int f(int, int);",
>> в объявлении надо уже писать "int f(int m, int n)"
> Я вообще имел в виду, что особенности синтаксиса (включая
> невозможность двум и более айдентифаерам идти подряд кроме как
> в формальном параметре (long long и ко считаются одним
> айдентифаером позволяют вначале разобрать синтаксис
> приблизительно, зато одним и тем же куском кода разбирать и
> объявления, и имплементации, и вызовы функций, а потом уже в
> каждом конкретном случае проверить, что выполняются
> дополнительные условия.
Ты меня прости, но я не вижу причины, почему это проще паскаля.
Напротив, есть все причины, почему оно _сложнее_.
> Ну, я сам компилятора ещё не писал, но мне кажется, что так
> можно сделать.
>> Насчёт того, что можно писать "ff2(int(int" сомневаюсь.
> Это откуда ж ты пишешь, что скомпилить нечем? =)
Если тебе интересно знать, какой компилятор отъедает почти все
ресурсы в последнее время, я могу включить учёт:
printf '/accounting/s/no/yes/\nw\n\q\n' | ed -s /etc/rc.conf
/etc/rc.d/accounting start
Могу тебя уверить, фигурных скобок там почти нет.
---
"Крепче держите попкорн, граждане, плохо ваше дело;
ща вылезет --- устроит всем полный Армагеддец!"
Да, но меня больше интересует эквивалентное утверждение: если язык не регулярен (или задаётся очень сложным регулярным выражением то и программисту разбирать тяжелее.
> почему это проще паскаля.
Код короче. Общая часть - структура вызова функции (он же - объявление и имплементация) плюс произвольное количество * и & - абстрагирована. Ни писателю компилятора, ни программисту не нужно держать в голове две принципиально разных схемы (имплементацию не будем считать, ладно).
>> программистом, то язык регулярен?
> Да, но меня больше интересует эквивалентное утверждение:
> если язык не регулярен (или задаётся очень сложным регулярным
> выражением то и программисту разбирать тяжелее.
"Разбирать" в смысле самому или в смысле писать парсер?
В любом случае утверждение небесспорное, но не лишено оснований.
>> почему это проще паскаля.
> Код короче. Общая часть - структура вызова функции (он же -
> объявление и имплементация) плюс произвольное количество * и & -
> абстрагирована. Ни писателю компилятора, ни программисту не
> нужно держать в голове две принципиально разных схемы
> (имплементацию не будем считать, ладно).
Я не вижу, как это проще паскаля.
В паскале, напомню, "прототипов" нет, там есть объявления,
которые бывают только вместе с телом или без такового, но
с припиской "forward". Из-за чего нет идиотизма, приводящего
к "function declaration isn't prototype".
---
...Я работаю антинаучным аферистом...
Понятно, что не бесспорное, но в качестве эвристики обычно работает. Вот, на примере паскалёвских флоатов: да, выражение 3..3 программист разбирает легко, а 3.,.3 - нет, очевидная связь!
> Я не вижу, как это проще паскаля.
Я не про одинаковость декларации и имплементации, и даже специально об этом сказал.
Я о том, что выражения "int i = f(g(i, j;" и "int f(int(int, int;" имеют одинаковую структуру, которую можно выписать как "... int f(int g(int i, int j;" (это невалидный стейтмент, на всякий случай). Более того, добавление любого количества указаний на indirection (* или &) сохраняет симметричность структуры. Поэтому обе можно сначала пропарсить одним и тем же простым дескентом, который строит дерево и считает атомом штуку вида "type name | type | name", и уже потом проверяет по контексту — объявление это или имплементация или вызов — какие именно атомы допустимы и допустимы ли операторы кроме * и &. Там есть некоторые кривые моменты, вроде "a * b", которые как бы показывают, что язык во-первых контекстно-зависим уже на уровне синтаксиса, во-вторых, что слово "потом" лишнее, смотреть в свои таблички и выяснять вид атомов компилятор должен сразу, во время разбора.
Плюс тот совершенно поразительный факт, что к любому объявлению можно дописать typedef (или статик или экстерн) и оно останется валидным — причём понятно, что для того, чтобы это работало, парсер нужно подпатчить совсем чуть-чуть: в случае "int i;" парсер делает, грубо говоря, variables["i"] = type, в случае "typedef int i;" он делает types["i"] = type;. Для указателей, функций и указателей на функции то же самое: дойдя до очередного имени он записывает его и/или выведенный тип в определяемые контекстом таблички, вот и всё.
В паскале же типы объявляются одним синтаксисом, переменные другим, инлайновых объявлений типов (вроде "int (*f(intint, int)" == "int -> (int -> int -> int)") и вовсе нет, ну, можно, конечно, утверждать, что это, скорее добро, но мне лично языки, описывающие рецепт приготовления фруктового пирога, не очень нравятся.
Кстати к предыдущему, меня твоё "Насчёт того, что можно писать "ff2(int(int" сомневаюсь." всё-таки очень удивило: неужели написать "echo 'ff2(int(int; int main;' > zzz.c ; gcc zzz.c" так тяжело? Тяжелее, чем написать те три строчки, которые ты написал в оправдание?
равно неубедительны. Да, паскаль есть куда улучшать, см. напр.
язык Ада, однако в том виде, в котором это сделано в сях, это
тришкин кафтан: здесь одно не так, там другое.
---
"Каждый имеет право на пользование родные языком..."
---
"Где-то в степях зацветает полынь,
Там за хребтом мир живёт, мир шумит..."
Оставить комментарий
Barbie29
кто может? Куда копать и че делать?Ну или сколько это стоит?
p.s. ради исскуства, как можно написать самый простой компилятор? ибо я сам не умею, но надо видать на асме, а в асм я так, слегка очень очень. Очено оное переходит в С. Короче, как компилятор написать на байткоде?