[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>
...

Теперь запустив сборку данного проекта вы получите автоматическую генерацию и сборку проекта интеграции.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.