Предварительный вариант документации на 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>
...
Теперь запустив сборку данного проекта вы получите автоматическую генерацию и сборку проекта интеграции.