Какой наиболее интересный и перспективный подход для реализации компилятора в C #? - PullRequest
4 голосов
/ 10 ноября 2011

Я только начинаю свой дипломный проект, который должен продлиться 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 месяцев, чтобы получить положительную оценку ...

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

Ответы [ 3 ]

5 голосов
/ 10 ноября 2011

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

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

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

2 голосов
/ 10 ноября 2011

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

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

Я бы предложил сделать нечто подобное для вашего проекта. Изначально разработайте его для вывода MSIL, который можно собрать с помощью ILASM. Таким образом, вы можете легко проверить вывод вашего генератора кода, прочитав сгенерированный код. Если вы уверены, что ваш генератор кода работает, добавьте параметр вывода, который будет использовать Reflection.Emit или Common Compiler Infrastructure.

2 голосов
/ 10 ноября 2011

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

...