Слушай, Cpphater, ты бы что ли пустые строки вставлял между своими и чужими мыслями. Будет проще читать... А то я так совсем передумаю быть твоим единомышленником.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Glagolev, Вы писали:
G>Здравствуйте, WolfHound, Вы писали:
WH>>Здравствуйте, Cpphater, Вы писали:
C>>>Разработка будет открытая (всё по BSD), основной язык имплементации С++, название языка 'Tany' WH>>С++ очень плохо подходит для разработки компиляторов. WH>>И вобще ИМХО язык нужно писать на самом себе.
G>ага, прям сразу на самом себе
Ничего смешного. Когда Вирт Паскаль придумывал (с Мейером, кажется), они сначала
написали код компилятора на Паскале, а потом отправили своего ассистента в 2-х недельный отпуск,
чтобы он там в машинные коды все перевел вручную.
Здравствуйте, Cpphater, Вы писали:
C>Имею желание разработать язык следующего, за С++, поколения, являющегося его идейным потомком и его же убийцей. C>Идейную наследственность вижу в кардинальном усилении метапрограммной составляющей. Одновременное, с этим, кардинальное удаление С рудиментов должно породить язык необычайной выразительной мощи.
Не вижу смысла придерживаться идеологии С++. Меня в последнее время очень заинтересовала функциональная парадигма, но не "чисто функциональная" (которая, ИМХО, скорее применима для математиков и ученых в прикладных пакетах типа матлаба), а комбинированная, реализованная в Scala и Nemerle. Ну и макросы Немерле — самая мощная метапрограммная система из всех, какие я знаю.
В С++ есть недостатки, мне этот язык нравится из-за того, что при всех его возможностях в нем остается низкоуровневость. Java и C# годятся для офисных программ, но не для настоящего системного программирования. И пусть говорят, что JIT-компиляция круче обычной... Она не круче, она просто другая. И любой язык-убийца должен поддерживать оба типа компиляции, причем желательно — одновременно в одном проекте.
Все разработчики новых языков не учитывают одной простой вещи: для того, чтобы реальные программисты стали писать на новом языке программы, красоты и выразительности самого языка недостаточно. Нужно, чтобы этот язык как можно более гладко интегрировался в существующий процесс разработки. В идеале, программист скачивает инсталляшку некоего языка "X", запускает ее — и вуаля, в Visual Studio (или в любой другой распространенной IDE) появлялись пункты "Add new "X" file to project", в MSDN — подробнейшая справка по языку "X" (желательно еще и переведенная на родной язык разработчика!) и пара учебников с примерами, при компиляции компилятор файлы *.cpp компилирует С++-овским компилятором, а файлы "X" — новым "X"-овсым, линкер корректно линкует разные объектники в один exe-шник... Нужно чтобы в файлах нового языка можно было свободно использовать все без исключения библиотеки того же С/С++, чтобы с новым языком работал отладчик, подсветка синтаксиса, автокомплит...
Вот если все эти условия будут выполнены, тогда и появится язык-убийца.
Здравствуйте, Smal, Вы писали:
S>Ничего смешного. Когда Вирт Паскаль придумывал (с Мейером, кажется), они сначала S>написали код компилятора на Паскале, а потом отправили своего ассистента в 2-х недельный отпуск, S>чтобы он там в машинные коды все перевел вручную.
А мне не нужен будет ассистент для подобного. С++ может считаться подмножеством TanyC. Любая программа на нём будет являться (быть может лишь только с небольшими лексическими изменениями) программой на TanyC.
Почему отступы делаешь то табами то пробелами? Бардачек однако.
Чтобы такого небыло включи в студии чтобы непечатыемые символы показывались. А чтобы в глаза не бросались сделай их бледносерыми.
А чем binary_procedure лучше всех остальных процедур?
object_visitor... будет просто огромным и пользоватся им будет ой не просто... Перешол бы на нормальный язык пока не поздно.
Ну это там где pattern matching есть:
// the special case for unary operators
| TT.TExpr.Call (TT.TExpr.OpCode (name), [parm], _) =>
append (name);
append ("(");
recurse (parm.expr);
append (")");
// the special case for infix binary operators
| TT.TExpr.Call (TT.TExpr.OpCode (name), [parm1, parm2], _) =>
append ("(");
recurse (parm1.expr);
append (" " + name + " ");
recurse (parm2.expr);
append (")")
// pretty print the list constructors
| TT.TExpr.Call (TT.TExpr.StaticRef (_, mem, _), _, _) when is_list_cons (mem) =>
print_list_constructors (expr)
// write all the other calls in prefix form
| TT.TExpr.Call (func /* PExpr */, parms /* list [Parm] */, _) =>
recurse (func);
append (" (");
print_fun_call_parms (parms);
append (")")
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Спасибо за замечания, WolfHound, постараюсь исправиться
binary_procedure я выделил как базовый класс для бинарных built-in процедур. (процедурами я называю функции выполняемые в компайл-тайм)
WH>object_visitor... будет просто огромным
почему? Количество визитируемых типов не должно превысить и десятка. Или это уже много?
Что касается перехода на другой язык... Это было бы неправильно идеологически... поэтому ложится в некоторый принцип. Сам говорил что язык надо делать на самом себе. С++ является подмножеством TanyC. Поэтому Nemerle мне не подходит
Здравствуйте, WolfHound, Вы писали:
WH>>>С++ очень плохо подходит для разработки компиляторов. CS>>Чё так? WH>Ни алгебраических типов. WH>Ни сравнения с образцом. WH>Ни нормальных макросов. WH>Ни сборщика мусора.
ни кофе не приносит девелоперу..
а можно пример как перечисленное выше используется для разработки компиляторов?.
я просто слишком далек от этого
Здравствуйте, neFFy, Вы писали:
FF>а можно пример как перечисленное выше используется для разработки компиляторов?. FF>я просто слишком далек от этого
Можно.
WH>>Ни алгебраических типов. WH>>Ни сравнения с образцом.
Позволяют гораздо проще работать с AST.
Например попробуй представить как это
будет выглядить на if'ах, визитерах и тп...
WH>>Ни нормальных макросов.
Например в томже AST есть куча методов которые можно тупо сгенерировать на основе содержания конкретного узла.
WH>>Ни сборщика мусора.
Следить за тем кто на кого ссылается и когда и кого можно удалить тот еще геморой.
ГЦ делает этот процесс сильно проще.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, c-smile, Вы писали:
WH>>>С++ очень плохо подходит для разработки компиляторов. CS>>Чё так? WH>Ни алгебраических типов. WH>Ни сравнения с образцом. WH>Ни нормальных макросов. WH>Ни сборщика мусора. WH>...
При разработки трансляторов лучше пользоваться генераторами кода. Удобней, проще, надежней.
Для C/C++ есть море, проверенных временем, тулзовин, генеращих парсреры, лексеры, асты, и т.д. Там есть и сопоставление с образцом и удобный способ описания астов, грамматик, трансформаций астов, вычисления атрибутов в астах и т.д.
Скажем, у нас есть полный парсер C# 2.0, с поддержкой препроцессора (его конструкции представлены в АСТе), полным разрешением имен, таблицей символов, построением АСТа, в котором находится даже комменты, возможностью парсинга файлов в формате UTF-8/UTF-16/ASCII. Парсер сделан с использованием средства Cocktail (генерит код на С). Объем всех исходников всего около 9000 строк (учитывая пустые строки и комментарии). Работает быстро, памяти жрет мало, расширять/дополнять удобно, выдаются исчерпывающие сообщения об синтаксических ошибках.
Здравствуйте, _Obelisk_, Вы писали:
WH>>Ни алгебраических типов. WH>>Ни сравнения с образцом. WH>>Ни нормальных макросов. WH>>Ни сборщика мусора. WH>>...
_O_>При разработки трансляторов лучше пользоваться генераторами кода. Удобней, проще, надежней. _O_>Для C/C++ есть море, проверенных временем, тулзовин, генеращих парсреры, лексеры, асты, и т.д. Там есть и сопоставление с образцом и удобный способ описания астов, грамматик, трансформаций астов, вычисления атрибутов в астах и т.д.
Гы... И ты думаешь, всего этого достаточно? И ты думаешь, что при лексическом анализе паттерн матчинг сильно помогает? А ты не задумывался, что нужно ещё сделать проверку (вывод) типов, перевести AST в промежуточное представление (а может быть, и в несколько промежуточных представлений — например, сначала в лямбду а затем в комбинаторы), сгенерить код? Не говоря конечно об оптимизациях.
_O_>Скажем, у нас есть полный парсер C# 2.0, с поддержкой препроцессора (его конструкции представлены в АСТе), полным разрешением имен, таблицей символов, построением АСТа, в котором находится даже комменты, возможностью парсинга файлов в формате UTF-8/UTF-16/ASCII. Парсер сделан с использованием средства Cocktail (генерит код на С). Объем всех исходников всего около 9000 строк (учитывая пустые строки и комментарии). Работает быстро, памяти жрет мало, расширять/дополнять удобно, выдаются исчерпывающие сообщения об синтаксических ошибках.
Ну и? Он только парсить умеет? Тогда что-то много 9000 строк. Ты что ли учёл сгенерированны код? Я бы в 2-3К строк уложился, будь у меня правильный генератор (из нах — 0.5К — только одна грамматика). А то все эти генераторы страдают похожестью на yacc.
_O_>Тоже самое для MSIL-а — где-то 2700 строк.
Здравствуйте, konsoletyper, Вы писали:
K>Гы... И ты думаешь, всего этого достаточно? И ты думаешь, что при лексическом анализе паттерн матчинг сильно помогает? А ты не задумывался, что нужно ещё сделать проверку (вывод) типов, перевести AST в промежуточное представление (а может быть, и в несколько промежуточных представлений — например, сначала в лямбду а затем в комбинаторы), сгенерить код? Не говоря конечно об оптимизациях.
Я писал вывод типов, семантический анализаторы, трансформации AST-ов в иное представление и др.
Паттерн матчинг используется при обработке AST-а ( в ходе семантического анализа, генерации кода, трансформации AST-a) для задания шаблонов узлов AST-а. Скажем, для binary expression с таким-то типом левого и правого аргумента назначить тип такой-то. Т.е. при том же выводе типов применяется.
А лексический анализ — это самое простейшее в трансляторе. Генераторы лексеров делают всю работу.
K>Ну и? Он только парсить умеет? Тогда что-то много 9000 строк. Ты что ли учёл сгенерированны код? Я бы в 2-3К строк уложился, будь у меня правильный генератор (из нах — 0.5К — только одна грамматика). А то все эти генераторы страдают похожестью на yacc.
Cocktail гораздо круче, чем yacc, но он платный.
9000 строк — это не генеренный код. Это спецификации для генератора.
Я же сказал, что не только парсит, но и строит таблицы символов, делает разрешение имен и семантический анализ. Если сможешь, представь тоже самое размером в 2-3К строк кода. Требования на парсер и построенный АСТ:
— полное покрытие спецификации C# 2.0
— в асте должны быть элементы представляющии директивы препроцессора (такие как #region и др)
— в асте должны быть представлены комментарии
— в асте должны быть позиции для каждого элемента
— должна быть нормальная система восстановления после ошибок и репорт о синтаксических и лексических ошибках
— парсер должен уметь парсить файлы в формате UTF-8 и UTF-16
— должен быть выделенный интерфейс для парсера и сканнера (ака. лексера)
— аст должен быть удобен для последующий обработки
— все должно быть платформонезависимым (работать под Win/Linux/Solaris)
Семантический анализ, вывод типов, разрешение имен не требую, ибо они в 2 — 3 килобайта не влезут
P.S.
Извини, но сколько реальных парсеров (или семантических анализаторов, кодогенераторов и т.п.) , которые используется в реальных коммерческих проектах, ты написал ?
Здравствуйте, _Obelisk_, Вы писали:
_O_>Я писал вывод типов, семантический анализаторы, трансформации AST-ов в иное представление и др.
И как, всё было просто, или прошлось опираться на костыли?
_O_>Паттерн матчинг используется при обработке AST-а ( в ходе семантического анализа, генерации кода, трансформации AST-a) для задания шаблонов узлов AST-а. Скажем, для binary expression с таким-то типом левого и правого аргумента назначить тип такой-то. Т.е. при том же выводе типов применяется.
Ага. Это как правило и есть немалая часть компилятора.
_O_>А лексический анализ — это самое простейшее в трансляторе. Генераторы лексеров делают всю работу.
Вот и я про то же. Но если их не юзать, то паттерн матчинг мало поможет, и ФЯ почти не даст выигрыша перед ИЯ без паттерн-матчинга.
K>>Ну и? Он только парсить умеет? Тогда что-то много 9000 строк. Ты что ли учёл сгенерированны код? Я бы в 2-3К строк уложился, будь у меня правильный генератор (из нах — 0.5К — только одна грамматика). А то все эти генераторы страдают похожестью на yacc.
_O_>Cocktail гораздо круче, чем yacc, но он платный.
А чем он круче кроме скорости и error handling?
_O_>9000 строк — это не генеренный код. Это спецификации для генератора.
_O_>Я же сказал, что не только парсит, но и строит таблицы символов, делает разрешение имен и семантический анализ. Если сможешь, представь тоже самое размером в 2-3К строк кода. Требования на парсер и построенный АСТ: _O_>- полное покрытие спецификации C# 2.0
Ага.
_O_>- в асте должны быть элементы представляющии директивы препроцессора (такие как #region и др)
Ага.
_O_>- в асте должны быть представлены комментарии
Ага.
_O_>- в асте должны быть позиции для каждого элемента
Элементарно.
_O_>- должна быть нормальная система восстановления после ошибок и репорт о синтаксических и лексических ошибках
Это вообще проблема нерешённая. Всякие Cocktail просто предоставляют хорошую эвристику. Тонны кода тут ничего не решают.
_O_>- парсер должен уметь парсить файлы в формате UTF-8 и UTF-16
И это проблема?
_O_>- должен быть выделенный интерфейс для парсера и сканнера (ака. лексера)
И что?
_O_>- аст должен быть удобен для последующий обработки
Ага
_O_>- все должно быть платформонезависимым (работать под Win/Linux/Solaris)
Ага.
_O_>Семантический анализ, вывод типов, разрешение имен не требую, ибо они в 2 — 3 килобайта не влезут
Может и не требуешь, но компилятор — это далеко не только парсер. То, что ты назвал, как правило реализуется дольше и сложнее, чем парсер/лексер. И в данном случае сопоставление с образцом, сборщик мусора и т.д. являются неплохим подпорьем.
_O_>P.S. _O_>Извини, но сколько реальных парсеров (или семантических анализаторов, кодогенераторов и т.п.) , которые используется в реальных коммерческих проектах, ты написал ?
Ни одного. Исключительно в самообразовательных целях. Возможно, мне ещё придётся писать парсер для коммерческого проекта. Так же планирую написать компилятор ML-образного языка для диплома, на OCaml. За парсер боюсь меньше всего, т.к. это штука простая. Вот разобраться в суперкомбинаторах и G-машине — это посерьёзнее будет... Зато я уже успел написать два генератора парсеров (один на Nemerle, можно найти в соотв. форуме). Кстати, если его доработать (вообще, серьёзно доработать), то можно запросто покрыть названные тобой пункты гораздо меньшим числом строк, чем 9К. Кстати, это всё благодаря тому, что в своём генераторе я ориентировался на преимущества, предоставляемые ФЯ.
Здравствуйте, konsoletyper, Вы писали:
K>Здравствуйте, _Obelisk_, Вы писали:
_O_>>Я писал вывод типов, семантический анализаторы, трансформации AST-ов в иное представление и др.
K>И как, всё было просто, или прошлось опираться на костыли?
Зависело от задач.
K>Вот и я про то же. Но если их не юзать, то паттерн матчинг мало поможет, и ФЯ почти не даст выигрыша перед ИЯ без паттерн-матчинга.
Генераторы надо юзать, ручками писать стоит только что-либо совсем простое.
K>А чем он круче кроме скорости и error handling?
Наличие языка для описания AST-а (на самом деле не только AST-а но и других, подобных структур), наличие языка для написания трансформаций AST-а (с pattern matching-ом), наличие языка для описания attribute evaluators для AST-ов. Возможность генерации парсеров с множеством точек входа. Генерит хорошую информацию о конфликтах в грамматике. Для AST-ов генерятся механизмы сериализации/десериализации и визуализации AST-а. Есть примочка, автоматически выводящая спецификацию для сканнера из грамматики.
Есть библиотека со всякими полезными штуками для решения сопутствующих задач возникающих при создании компиляторов (хэширование строк, управление памятью и др)
Хорошая документация и примеры. Плюс поддержка со стороны разработчиков. Но, к сожаленью, тул платный (есть какая-то бесплатная версия, но сильно убогая)
_O_>>- должна быть нормальная система восстановления после ошибок и репорт о синтаксических и лексических ошибках
K>Это вообще проблема нерешённая. Всякие Cocktail просто предоставляют хорошую эвристику. Тонны кода тут ничего не решают.
Главное, что тот же Cocktail берет заботу об этом на себя и решает ее на хорошем уровне.
_O_>>- парсер должен уметь парсить файлы в формате UTF-8 и UTF-16 K>И это проблема?
Нет, но надеюсь, ты не забыл, что в тексте программы могут присутствовать символы в виде \u01d7 \u01e0 и т.д ? Сканер должен такое поддерживать.
K>Может и не требуешь, но компилятор — это далеко не только парсер. То, что ты назвал, как правило реализуется дольше и сложнее, чем парсер/лексер. И в данном случае сопоставление с образцом, сборщик мусора и т.д. являются неплохим подпорьем.
Задачи из области разработки компиляторов возникают отнюдь не только при разработки компиляторов. У нас они возникают при создании генераторов из формальных моделей, импорта и трансформации программ (source-to-source transformations), создании таких фич как IntelliSense, поддержка рефакторинга и т.п
Собственно сейчас околокомпиляторных задач гораздо больше, чем потребности в разработки именно новых компиляторов.
K>Ни одного. Исключительно в самообразовательных целях. Возможно, мне ещё придётся писать парсер для коммерческого проекта. Так же планирую написать компилятор ML-образного языка для диплома, на OCaml. За парсер боюсь меньше всего, т.к. это штука простая. Вот разобраться в суперкомбинаторах и G-машине — это посерьёзнее будет... Зато я уже успел написать два генератора парсеров (один на Nemerle, можно найти в соотв. форуме). Кстати, если его доработать (вообще, серьёзно доработать), то можно запросто покрыть названные тобой пункты гораздо меньшим числом строк, чем 9К. Кстати, это всё благодаря тому, что в своём генераторе я ориентировался на преимущества, предоставляемые ФЯ.
То, что сам написал пару генераторов, это похвально
Только еще раз повторю — 9К — это с выводом типов, разрешением имен и таблицей символов. Собственно парсер со сканнером там где-то 2700 занимают.
А твой генератор парсеров какие парсеры генерит ? LL, LR(k), LALR(k) ? Детектит ли он конфликты в грамматике и какую информацию выдает ? Предоставляет ли средства для динамического резолвинга конфликтов ? Содержит ли какой-нибудь язык для описания AST-ов ? Имеются ли возможности для задания правил вычисления атрибутов в AST-е ?
Сделать в самообразовательных целях генератор парсеров не трудно. А вот сделать из этого продукт и довести до ума — тяжело. Я верю, что всегда можно сделать тул круче уже существующих. К сожаленью, это происходит редко. Плюс того же Cocktail-я в том, что это интегрированная система тулов, в которых каждый тул с каждым легко соеденить. Проектирование такой архитектуры требует времени (Cocktail с 1988-го года развивается)
Когда я учился в универе, мне казалось, что все можно написать за пару ночей (и ведь действительно писалось!) Потом реализм наступил.
P.S.
Хочешь задачку, полезную для общества ? — Подумай надо созданием UML Virtual Machine. Т.е. над машиной, которая могла бы интерпретировать UML-модели (только бери последнюю версию стандарта, где action semantics есть). Это позволит симулировать модели без необходимости кодогенерации исполняемого приложения. А симуляция моделей — вещь нужная всяким военным, аэрокосмическим, телекоммуникационным компаниям (правда западным, не нашим).
Здравствуйте, _Obelisk_, Вы писали:
K>>И как, всё было просто, или прошлось опираться на костыли?
_O_>Зависело от задач.
Я не про то. Я про тулзы, которыми пользовались. Писали на C# или C++? Тулзы позволяли адекватно отражать задачу, или приходилось трахаться?
K>>Вот и я про то же. Но если их не юзать, то паттерн матчинг мало поможет, и ФЯ почти не даст выигрыша перед ИЯ без паттерн-матчинга.
_O_>Генераторы надо юзать, ручками писать стоит только что-либо совсем простое.
Двумя руками за. Но я не про то. Почитай ещё раз внимательно выше по ветке.
K>>А чем он круче кроме скорости и error handling?
_O_>Наличие языка для описания AST-а (на самом деле не только AST-а но и других, подобных структур), наличие языка для написания трансформаций AST-а (с pattern matching-ом)
А вот не проще ли было сделать генерацию AST в ФЯ, которых хорошо подошёл бы для трансформации AST (например, Haskell, OCaml), чем изобретать велосипедную, нверняка не самую лучшую реализацию?
_O_>, наличие языка для описания attribute evaluators для AST-ов. Возможность генерации парсеров с множеством точек входа. Генерит хорошую информацию о конфликтах в грамматике. Для AST-ов генерятся механизмы сериализации/десериализации и визуализации AST-а. Есть примочка, автоматически выводящая спецификацию для сканнера из грамматики.
А умеет автоматически генерить правила для типовых случаев, чтобы не приходилось, как в yacc, справа от каждого правила писать { код }? А язык описания грамматики какой — yacc-образный, или полноценный BNF?
_O_>Есть библиотека со всякими полезными штуками для решения сопутствующих задач возникающих при создании компиляторов (хэширование строк, управление памятью и др)
Хэширование строк и управление памятью и так есть в любой нормально библиотеке нормального языка. Или этого не достаточно?
K>>И это проблема?
_O_>Нет, но надеюсь, ты не забыл, что в тексте программы могут присутствовать символы в виде \u01d7 \u01e0 и т.д ? Сканер должен такое поддерживать.
Ага, и это не вызывает особых проблем. Примерно так (выдержка из спецификации, по которой генерится рабочий лексер, сделано копипастом из стандарта):
K>>Может и не требуешь, но компилятор — это далеко не только парсер. То, что ты назвал, как правило реализуется дольше и сложнее, чем парсер/лексер. И в данном случае сопоставление с образцом, сборщик мусора и т.д. являются неплохим подпорьем.
_O_>Задачи из области разработки компиляторов возникают отнюдь не только при разработки компиляторов. У нас они возникают при создании генераторов из формальных моделей, импорта и трансформации программ (source-to-source transformations), создании таких фич как IntelliSense, поддержка рефакторинга и т.п _O_>Собственно сейчас околокомпиляторных задач гораздо больше, чем потребности в разработки именно новых компиляторов.
Мы говорили не об околокомпиляторной задаче, а о компиляторе. Утверждение, что компилятор тяжело написать на языке, не обладающем определёнными возможностями, никак нельзя опровергнуть тем, что околокомипляторные задачи запросто решаются и без этих средств. Наоборот, тот же IntelliSense (его визуальная составляющая, поддержка в тектовом редакторе и т.п.) проще бы решалась на языке, обладающем хорошими "компонентными" возможностями, т.е. каком-нибудь C#, Java и т.п.
_O_>То, что сам написал пару генераторов, это похвально _O_>Только еще раз повторю — 9К — это с выводом типов, разрешением имен и таблицей символов. Собственно парсер со сканнером там где-то 2700 занимают.
Ну, 2700 — это ещё жить можно Вывод типов в C# — штука несложная, т.к. она производится только для generic'ов. Хотя и алгоритм вывода типов в системе типов Хиндли-Милнера тоже весьма прост. Правда, подобное утверждение верно только для классической системы типов Хиндли-Милнера. Если в неё добавить type classes, перегрузку или что-то в этом роде, написание вывода типов на каком-нибудь C++ превращается в сущий ад.
_O_>А твой генератор парсеров какие парсеры генерит ? LL, LR(k), LALR(k) ?
LALR. Хотел так же добавить LL(*) и GLR, но руки не дошли.
_O_> Детектит ли он конфликты в грамматике и какую информацию выдает ? Предоставляет ли средства для динамического резолвинга конфликтов ?
Детектит, не не репортит, руки не дошли. Многие сам пытается разрешить. Всё равно, в грамматике серьёзного языка вроде C# такого не напишешь:
с соответсвующими %left, %right и %nonassoc. Там приходится следовать спецификаии из стандарта. Или я чего-то не догоняю?
_O_>Содержит ли какой-нибудь язык для описания AST-ов ?
Нет. А зачем?
_O_>Имеются ли возможности для задания правил вычисления атрибутов в AST-е ?
Это как?
_O_>Сделать в самообразовательных целях генератор парсеров не трудно. А вот сделать из этого продукт и довести до ума — тяжело. Я верю, что всегда можно сделать тул круче уже существующих. К сожаленью, это происходит редко. Плюс того же Cocktail-я в том, что это интегрированная система тулов, в которых каждый тул с каждым легко соеденить. Проектирование такой архитектуры требует времени (Cocktail с 1988-го года развивается)
_O_>Когда я учился в универе, мне казалось, что все можно написать за пару ночей (и ведь действительно писалось!) Потом реализм наступил.
У меня уже давно реализм наступил, когда я на работе впервые столкнулся с правилом "20% функциональности требует 80% времени". Сделать круче Coctail достаточно просто — для этого нужно просто ориентироватся не на C++/C#/Java, а на что-то функциональное. И при этом не заниматься тупым компированием yacc.
_O_>P.S. _O_>Хочешь задачку, полезную для общества ? — Подумай надо созданием UML Virtual Machine. Т.е. над машиной, которая могла бы интерпретировать UML-модели (только бери последнюю версию стандарта, где action semantics есть). Это позволит симулировать модели без необходимости кодогенерации исполняемого приложения. А симуляция моделей — вещь нужная всяким военным, аэрокосмическим, телекоммуникационным компаниям (правда западным, не нашим).
Не, на мне и так висит несколько задачек, полезных для общества Всякие там генераторы и компиляторы — это исключительно в свободное время
Здравствуйте, konsoletyper, Вы писали:
K>Я не про то. Я про тулзы, которыми пользовались. Писали на C# или C++? Тулзы позволяли адекватно отражать задачу, или приходилось трахаться?
Cocktail + C++. Для некоторых задач (писали прямой импорт файлов из Rational Rose и Borland Together Architect) я сделал свой генератор объектно-ориентированных AST-ов. Он генерит системы С++ классов, описывающих внутреннюю модель данных этих продуктов из спецификации на UML. В данном случае, для описания AST-а UML подошел лучше, чем Cocktail. Была заточка на эффективность (надо было парсить файлы размером в 400 мегов и больше) и удобство последующих трансформаций.
Подобная штучка из Eclipse-а (в EMF есть) зависала при импорте моделей размером от 15 мегов. Так что Java была отброшена сразу. С# не рассматривался по тем же причинам (плюс тогда была лишь его первая версия, без generic-ов).
K>А вот не проще ли было сделать генерацию AST в ФЯ, которых хорошо подошёл бы для трансформации AST (например, Haskell, OCaml), чем изобретать велосипедную, нверняка не самую лучшую реализацию?
Не, специально заточенные языки для описания AST-ов и их трансформаций гораздо удобней, чем любой язык программирования общего назначения.
K>А умеет автоматически генерить правила для типовых случаев, чтобы не приходилось, как в yacc, справа от каждого правила писать { код }? А язык описания грамматики какой — yacc-образный, или полноценный BNF?
Умеет. Язык описания грамматики — EBNF, BNF, плюс поддерживает yacc-йи формат.
K>Хэширование строк и управление памятью и так есть в любой нормально библиотеке нормального языка. Или этого не достаточно?
Там заточка на производительность. Стандартные средства не всегда хороши.
K>Мы говорили не об околокомпиляторной задаче, а о компиляторе. Утверждение, что компилятор тяжело написать на языке, не обладающем определёнными возможностями, никак нельзя опровергнуть тем, что околокомипляторные задачи запросто решаются и без этих средств. Наоборот, тот же IntelliSense (его визуальная составляющая, поддержка в тектовом редакторе и т.п.) проще бы решалась на языке, обладающем хорошими "компонентными" возможностями, т.е. каком-нибудь C#, Java и т.п.
Я на С++ такое делал. C#/Java работу сильно не облегчат.
K>Ну, 2700 — это ещё жить можно Вывод типов в C# — штука несложная, т.к. она производится только для generic'ов. Хотя и алгоритм вывода типов в системе типов Хиндли-Милнера тоже весьма прост. Правда, подобное утверждение верно только для классической системы типов Хиндли-Милнера. Если в неё добавить type classes, перегрузку или что-то в этом роде, написание вывода типов на каком-нибудь C++ превращается в сущий ад.
Не столь все страшно. Я писал вывод типов, name resolution, semantic analyzer на С++ для UML 2.0, в котором есть перегрузка операций и операторов, множество неявных конверсий, шаблоны типов и операций в духе С++ (и даже кой в чем круче) и куча специфических вещей. Все это работает в online-режиме т.е. модель чекается и пересвязывается постоянно, когда юзер ее меняет.
Самое серьезная проблема здесь была — как определить степень воздействия изменения модели. Т.е. если мы переименовали класс, то какие части модели необходимо перечекать (переименование может привести к конфликту имен или наооборот, убрать конфликт)
Да, вывод типов — это ведь не только для generic-ов. Определить тип выражения "a + b" — это тоже вывод типов. Собственно, даже определить тип литерала (например числа 1) не всегда тривиально. Например, в таком специфическом языке как SDL, тип литерала зависит от его контекста и там в одном месте тип '1' будет Integer, а в другом 'Real' а в треьем — какой-нибудь 'Time'.
K>Детектит, не не репортит, руки не дошли. Многие сам пытается разрешить. Всё равно, в грамматике серьёзного языка вроде C# такого не напишешь:
K>
K>с соответсвующими %left, %right и %nonassoc. Там приходится следовать спецификаии из стандарта. Или я чего-то не догоняю?
Вот пример конфликтов в грамматике Шарпа (есть и другие) :
(x) -y
это cast expression или parenthesized expression ?
или
A < B, C >> D // shift or type arguments ?
Конфликты решаются динамически, с помощью предикатов, которые делают lookahead.
У тебя генератор поддерживает задание каких-либо condition-ов на правила в грамматике для динамического резолвинга подобных конфликтов ?
_O_>>Содержит ли какой-нибудь язык для описания AST-ов ? K>Нет. А зачем?
Для описания AST-а, как самостоятельной сущности. Нужно и удобно на практике.
_O_>>Имеются ли возможности для задания правил вычисления атрибутов в AST-е ?
Это позволяет существенно упростить написание семантического анализа.
Понятия синтезируемый атрибут/наследуемый атрибут, атрибутивная грамматика, higher order attribute grammar знакомы ?
K>Не, на мне и так висит несколько задачек, полезных для общества Всякие там генераторы и компиляторы — это исключительно в свободное время
Ну а у меня всякие генераторы — это почти прямая деятельность, которая поглощает и свободное время А вот времени на разработку всех идей не хватает.
Здравствуйте, x-code, Вы писали:
XC>Все разработчики новых языков не учитывают одной простой вещи: для того, чтобы реальные программисты стали писать на новом языке программы, красоты и выразительности самого языка недостаточно. Нужно, чтобы этот язык как можно более гладко интегрировался в существующий процесс разработки. В идеале, программист скачивает инсталляшку некоего языка "X", запускает ее — и вуаля, в Visual Studio (или в любой другой распространенной IDE) появлялись пункты "Add new "X" file to project", в MSDN — подробнейшая справка по языку "X" (желательно еще и переведенная на родной язык разработчика!) и пара учебников с примерами, при компиляции компилятор файлы *.cpp компилирует С++-овским компилятором, а файлы "X" — новым "X"-овсым, линкер корректно линкует разные объектники в один exe-шник... Нужно чтобы в файлах нового языка можно было свободно использовать все без исключения библиотеки того же С/С++, чтобы с новым языком работал отладчик, подсветка синтаксиса, автокомплит...
XC>Вот если все эти условия будут выполнены, тогда и появится язык-убийца.
Нуу... блин! Ты конечно прав. Но ты хочешь чтобы ребенок вел себя как взрослый.
Когда x-code подрастет, он это поймет. А когда повзрослеет — перестанет играть в
"те же яйца только в профиль". Может быть даже научится делать из С++ тот язык,
который ему нужен для текущей задачи. Но это ближе к пенсии