[Nitra] Nitra.LanguageCompiler.exe
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.15 20:25
Оценка: 51 (3)
Предварительный вариант документации на Nitra.LanguageCompiler

Nitra.LanguageCompiler.exe – это утилита командной строки которая по описанию языка и параметрам командной строки генерирует проект интеграции с Microsoft Visual Studio (VS).
Ранее мы создавали один, единый плагин для всех языком созданных с помощью Nitra, но, по ряду причин, мы отказались от этого перейдя к генерации проектов интеграции для отдельных языков. Этот подход:
* позволил избежать «хаков» необходимых для обхода архитектурных особенностей VS и ReSharper;
* позволяет сделать языки созданные на базе Nitra более независимыми;
* а также упростит ручное расширение проектов интеграции.
Опции командной строки
Nitra.LanguageCompiler.exe флаги [сборки Nitra-парсера]
Флаги:
-lang:строка: Файл спецификации языка.
-out:строка: Путь в котором будет сгенерирован проект интеграции для языка.
-newguids, -renewguids, -guids+/-: Сгенерировать новые GUID для проекта. По умолчанию, Nitra.LanguageCompiler.exe пытается взять GUID-ы использованные в прошлой версии проекта. Они считываются из файла Constants.cs. Если прошлая версия файла существует и задана опция командной строки «-guids-» (или не заданы вовсе), GUID-ы берутся из нее. Если задана опция командной строки «-guids+», то генерируются новые версии GUID-ов.
-snk, -keyfile:строка: Путь к snk-файлу с помощью которого будет подписываться сборка интеграции.
-bin:STRING: Путь к дополнительным бинарным файлам которые нужно включить в проект интеграции. Эти файлы копируются в подкаталог ExternalDependences и включаются в проект.

Список сборок содержащих парсер Nitra – они добавляются в проект интеграции и используются для парсинга файлов языка.
Пример опций командной строки используемых для генерации проекта интеграции для самой Nitra:
Nitra.LanguageCompiler.exe /lang:..\..\Nitra.nlang /out:..\..\..\ /bin:.\ .\Nitra.Grammar.dll

Файл спецификации языка

Файл спецификации языка описывает данные необходимые для генерации интеграции с VS для некоторого языка. Вот как выглядит такой файл для самой Nitra:
language Nitra
{
  display name = Nitra;
  extension = .nitra;
  company   = Jet Brains;
  namespace = Nitra;

  syntax module NitraSyntax start rule Start;

  span class Keyword          = Blue;
  span class Operator         = Olive;
  span class Number           = DarkCyan;
  span class OpenBrace        = DarkGray;
  span class CloseBrace       = DarkGray;
  span class String           = Maroon;
  span class StringEx         = Maroon;
  span class Char             = Red;
  span class InlineComment    = Green;
  span class MultilineComment = Green;
}

Здесь language Nitra задает имя (Nitra) для языка. Это имя используется для формирования имен многих элементов внутри проекта интеграции с VS. Данное имя должно начинаться с буквы и содержать только буквы, цифры и знак «_». Например, для языка «C#» данное имя должно быть чем-то вроде «NitraCSharp». Данное имя должно быть уникальным. Так что лучше включать в него префикс «Nitra» или имя вашей организации. Например, имя «CSharp» неприемлемое, так как стандартная интеграция для C# от Microsoft использует именно его и вы получите исключение во время выполнения.
«display name» – имя языка используемое в GUI и прочих местах. Данном имя может содержать любые UNICODE-символы. Например, для языка C# оно может быть «C#».
«extension» – описывает расширение файла ассоциируемое с данным языком.
«company» – описывает название организации создавшей язык или имя его автора. Эта строка будет видна в диалоговых окнах VS.
«namespace» – задает название пространства имен используемого по умолчанию в проекте интеграции с VS.
«syntax module ... start rule» – задает имя синтаксического модуля и стартового правила с которых нужно начинать парсинг. «syntax module» может встречаться более одного раза, что позволяет задать части парсера помещенные в различные сборки. При этом, конструкция «start rule» может встречаться только один раз, так как стартовое правило должно быть ровно одно. Синтаксические модули и правило берутся из сборок парсера задаваемых в командной строке.
«span class» – может встречаться более одного раза и задает описание стиля подсветки который можно использовать в парсерах языка. Значения стилей потом можно переопределить в VS (Tools\Options…\Fonts and Colors). При этом имя «Display item» в «Fonts and Colors» будет формироваться из «display name» + " " + «span class», так что оно не будет пересекаться с аналогами из других языков. Например, «Keyword» будет иметь имя «Nitra Keyword» для Nitra и «C# Keyword» для NitraCSharp.
Все перечисленные конструкции можно вносить внутри конструкции «language» в любом порядке.

Шаблоны

Nitra.LanguageCompiler.exe генерирует C#-проект на основе файлов шаблонов. Они должны находиться рядом с Nitra.LanguageCompiler.exe в потдкаталоге Templates. Если изменить шаблоны, генерируемый код изменится соответствующим образом. Nitra.LanguageCompiler.exe производит замену «заполнителей» (placeholders) на значения берущиеся из файл спецификации языка и опций командной строки.

Заключение

В результате работы Nitra.LanguageCompiler.exe генерируется C#-проект после сборки которого получается плагин к VS. Его можно проинсталлировать запустив *VsPackage.vsix-файл. После этого в VS будет доступна поддержка для вашего языка.
Сборку плагина к VS можно включить в ваш процесс сборки с помощью следующего трюка. Можно создать проект C# (типа DLL). Удалить из него все файлы *.cs. Добавить в него ссылки на все необходимые сборки:
* Nitra.VisualStudio.dll
* Nemerle.dll
* Nitra.Runtime.dll
* Nitra.Core.dll
* MyLang. Grammar.dll – сборка содержащая парсер вашего языка.
Добавить в него файл спецификации вашего языка. Открыть файл проекта в текстовом редакторе, раскоментровать раздел «<Target Name="AfterBuild">» и добавить в него следующие строки:
...
<ItemGroup>
 <NLang Include="MyLang.nlang" />
</ItemGroup>
...
<Target Name="AfterBuild">
  <Exec Command="$(NitraPath)\Nitra.LanguageCompiler.exe /lang:..\..\MyLang.nlang /out:..\..\Output\ /bin:.\ .\MyLang.Grammar.dll" WorkingDirectory="$(TargetDir)" />
  <MSBuild Projects="$(MyLangVsPackagePath)" Properties="Platform=x86; Configuration=$(Configuration)" />
</Target>
...

Теперь запустив сборку данного проекта вы получите автоматическую генерацию и сборку проекта интеграции.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [Nitra] Nitra.LanguageCompiler.exe
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 27.02.15 20:41
Оценка:
А он может генерировать независимые от студии компиляторы?
Ce n'est que pour vous dire ce que je vous dis.
Отредактировано 27.02.2015 20:41 Don Reba . Предыдущая версия .
Re[2]: [Nitra] Nitra.LanguageCompiler.exe
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.15 20:53
Оценка:
Здравствуйте, Don Reba, Вы писали:

DR>А он может генерировать независимые от студии компиляторы?


Нет. По крайне мере — пока.

На мой взгляд, в этом нет особого смысла.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [Nitra] Nitra.LanguageCompiler.exe
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 28.02.15 07:49
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>На мой взгляд, в этом нет особого смысла.


Особого нет. В моём случае, сценаристу немного проще запустить процессор диалогов для игры из командной строки, чем устанавливать студию. Даже не коммерческий проект.
Ce n'est que pour vous dire ce que je vous dis.
Отредактировано 28.02.2015 8:01 Don Reba . Предыдущая версия .
Re[4]: [Nitra] Nitra.LanguageCompiler.exe
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.15 02:14
Оценка:
Здравствуйте, Don Reba, Вы писали:

DR>Особого нет. В моём случае, сценаристу немного проще запустить процессор диалогов для игры из командной строки, чем устанавливать студию. Даже не коммерческий проект.


Создать консольную запускалку для готового компилятора — это работа на час.

В компиляторе куда важнее будет: типизация, трансформация код и генерация чего-то исполнимого. Пока что мы не обеспечиваем всего этого. Но мы работаем над этим. Поэтапно будем реализовывать все это. Вот это и будет помощью в создании компилятора. Ну, а создание самого ехе-шника может потом и автоматизируем. Это уже совсем мелочи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.