Какой самый интересный и многообещающий подход к реализации компилятора на C#?

Я только в начале своего дипломного проекта, который должен длиться 6 месяцев. Цель проекта — реализовать .Net-компилятор для одного скриптового языка. У меня была компиляторная конструкция в качестве предмета в моей учебной программе, и я знаю основные шаги по реализации компилятора в целом, но мы использовали Bison и простой компилятор с GCC в качестве серверной части, и поэтому я мало знаю о реализации компиляторов. на платформе .Net.

Проведя некоторые исследования по этой теме, я нашел следующие альтернативные решения для генерации кода (я не говорю о других важных частях компилятора, таких как синтаксический анализатор - здесь это выходит за рамки):

  1. Прямое создание кода с помощью Reflection.Emit.
  2. Использование абстракции Common Compiler Interface по сравнению с Reflection .Emit для автоматизации генерации некоторого кода.
  3. Использование CodeDOM для компиляции C# и VB во время выполнения.
  4. Появился новый C# «компилятор как услуга» под названием Roslyn, доступен как CTP сейчас.
  5. DLR предлагает поддержку динамической генерации кода и имеет некоторые интерфейсы для генерации кода во время выполнения. через деревья выражений и т. д.
  6. Mono поставляется с библиотекой Mono.Cecil, которая, похоже, также имеет некоторые функции для генерации кода.

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

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

Заранее спасибо, Александр.


person Alexander Galkin    schedule 09.11.2011    source источник
comment
Обратите внимание, что Roslyn — это просто толстая оболочка вокруг ваших 1, 2 и 3.   -  person SLaks    schedule 10.11.2011
comment
@SLaks, я думаю, что Roslyn на самом деле не использует CodeDOM (# 3).   -  person svick    schedule 10.11.2011
comment
Я не был уверен в этом. Я подозреваю, что ты прав.   -  person SLaks    schedule 10.11.2011
comment
Какой язык вы бы предпочли? Динамичный, статичный?   -  person Dykam    schedule 10.11.2011
comment
Мое личное понимание состоит в том, что имело значение только одно. Напишите свой парсер. Как только вы это сделаете, все остальное просто. С лексером не так уж сложно работать, генератор кода тривиален, когда парсер работает. Худшее, что вы можете сделать, это оставить анализатор инструменту.   -  person Hans Passant    schedule 10.11.2011
comment
@HansPassant: я спрашиваю не о парсере, а о лучшем способе генерации кода. Конечно, написать синтаксический анализатор тоже очень сложно, но в этом вопросе он выходит за рамки.   -  person Alexander Galkin    schedule 10.11.2011
comment
@Dykam: это статически типизированный язык, поэтому нет необходимости в выводе типов и утином вводе во время выполнения.   -  person Alexander Galkin    schedule 10.11.2011


Ответы (3)


Если вам нужен более простой способ, и ваш язык можно разумно перевести на C#, я бы рекомендовал вам сгенерировать код C# (или аналогичный) и скомпилировать его. Рослин, вероятно, была бы лучшей в этом. Судя по всему, CCI тоже может это сделать, используя код CCI, но я никогда этим не пользовался. Я бы не рекомендовал CodeDOM, потому что он не поддерживает такие функции, как статические классы или методы расширения.

Если вам нужен больший контроль или вы хотите перейти на более низкий уровень, вы можете сгенерировать CIL напрямую, используя Reflection.Emit. Но это будет (гораздо) больше работы, особенно если вы не знакомы с CIL. Я думаю, что Cecil можно использовать таким же образом, но он предназначен для чего-то другого, и я не думаю, что он дает какие-либо преимущества перед Reflection.Emit.

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

person svick    schedule 10.11.2011

Boo — это язык/компилятор, ориентированный на интерфейс командной строки. Похоже, это открытый исходный код, поэтому вы можете изучить, как они это делают.

person Sam Axe    schedule 09.11.2011
comment
Очень интересное предложение! Я читал книгу DSL с Boo и даже использовал Boo (как скриптовый движок) в одном из моих рабочих проектов, но я никогда не рассматривал его со стороны конструкции компилятора. спасибо! - person Alexander Galkin; 10.11.2011

Раньше, когда я писал компиляторы, я писал на ассемблере (то есть исходный код на ассемблере), который затем запускал через системный ассемблер. Таким образом, я мог легко видеть, что я генерировал. Читать mov ax, bx (сборку x86) намного проще, чем декодировать коды операций HEX.

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

Я бы предложил сделать что-то подобное для вашего проекта. Сначала разработайте его для вывода MSIL, который можно собрать с помощью ILASM. Таким образом, вы можете легко проверить вывод вашего генератора кода, прочитав сгенерированный код. Убедившись, что ваш генератор кода работает, добавьте параметр вывода, который будет использовать Reflection.Emit или общую инфраструктуру компилятора.

person Jim Mischel    schedule 09.11.2011
comment
Интересное предложение, спасибо! Вывод MSIL удобен для целей отладки и оптимизации компилятора. В любом случае, я думаю сначала написать транслятор на C#, а потом реализовать свой собственный компилятор, ибо оптимизация компилятора совсем не проста и прозрачна. - person Alexander Galkin; 10.11.2011