IronText — это библиотека для создания DSL и языков программирования под .Net с
низким уровнем сложности, и в то же время, достаточно мощная для создания любых
контекстно-свободных языков.
— Синтаксические и лексические правила описаны полностью с помощью .Net-овых типов
и пользовательских атрибутов
— Поддерживает создание любых контекстно-свободных языков, включая языки заданные
неоднозначными грамматиками
— Поддержка словарей лексических и синтаксических правил, которые могут быть
использованы в разных языках
— Generic-методы могут быть использованы в качестве "шаблонов правил"
— Позволяет задать язык как абстракцию с помощью интерфейсов и абстрактных
классов. В результате такая абстракция может иметь несколько реализаций для
различных задач парсинга, компиляции и т.д.
— Язык может быть унаследован от другого без доступа к исходному коду
базового языка.
— Язык может быть вложен в другой язык с совместимыми лексическими правилами
— Встроенная обработка ошибок
— Встроенная отслеживание позиции (строка, столбец)
— Сканер поддерживает переключаемые *режимы* которые позволяют обрабатывать сложные
лексические элементы, такие как вложенные комментарии
Технические детали
------------------
Парсер: LALR1, RNGLR.
Сканер: DFA скомпилировнный в RE2C-подобный .net код.
Здравствуйте, Sucaba, Вы писали:
S>IronText — это библиотека для создания DSL и языков программирования под .Net с S>низким уровнем сложности, и в то же время, достаточно мощная для создания любых S>контекстно-свободных языков.
Что-то название навеяло о http://irony.codeplex.com/ .
Здравствуйте, hardcase, Вы писали:
H>Одного не понимаю — зачем парсеры в рантайме собирать?
Не припоминаю чтобы где-то в документации было сказано о рантайме.
Но подозреваю что так работает Irony. IronText, по-умолчанию,
работает через msbuild, но может работать и в рантайме если вы
положите рядышком IronText.Compiler.dll и Cecil.Mono.dll.
В любом случае, идея в том, что вам не нужно думать как прикрутить
инструменты вроде ANTLR к вашему проекту.
К сожалению, пока не осилил описание билд-процесса в документации,
но если вы пользуетесь nuget-ом, то все должно работать без проблем.
Здравствуйте, fddima, Вы писали:
F>Здравствуйте, Sucaba, Вы писали:
S>>IronText — это библиотека для создания DSL и языков программирования под .Net с S>>низким уровнем сложности, и в то же время, достаточно мощная для создания любых S>>контекстно-свободных языков. F> Что-то название навеяло о http://irony.codeplex.com/ .
На самом деле, плагиат или мода "Iron" тянетcя еще из IronPython, IronRuby, ...
Думаю префикс Iron теперь ассоциируется с разработкой языков под .Net.
С другой стороны, у IronText и Irony есть и другие общие особенности:
— Обе являются библиотеками для парсинга
— Грамматика задается непосредственно в c#
На этом, наверное, сходство и заканчивается. Как сказано в [ur=https://github.com/sucaba/IronTextLibrary/blob/master/Doc/UserGuide.md]User Guide[/url],
IronText отличается от Irony более мощным алгоритмом парсинга (GLR) и более
читабельным, даже интуитивным (для c# программиста), представлением грамматики языка.
Здравствуйте, Sucaba, Вы писали:
S>На самом деле, плагиат или мода "Iron" тянетcя еще из IronPython, IronRuby, ... S>Думаю префикс Iron теперь ассоциируется с разработкой языков под .Net.
Я никоим образом ничего такого не имел ввиду. Просто сходу вспомнился уже старенькая библиотека, с похожим названием и нацеленная на тоже.
Здравствуйте, Sucaba, Вы писали:
S>В любом случае, идея в том, что вам не нужно думать как прикрутить S>инструменты вроде ANTLR к вашему проекту.
Да, вроде не так и сложно прикручивается...
Его (ANTLR) главная беда — полученное в результате парсинга AST ни разу не типизированное (точнее там все узлы одного типа), и его дальнейшая обработка довольно муторная задача. Это поведение можно поменять, но предлагаемы для этого методы не слишком удобны.
Как в вашей библиотеке реализуется такой сценарий разбора: исходный текст -> (парсер) -> AST -> (код обработки AST) -> результат.
Т.е. говоря коротко — как получить все AST и что оно собой будет представлять.
В тех примерах, которые я нашел (но может что-то упустил) вся полезная работа зашивается в Actions, которые срабатывают на конкретное синтаксическое правило.
Что-то типа такого (это из примера калькулятора):
[Parse(_, "+", _)]
public double Plus(double x, double y) { return x + y; }
[Parse(_, "-", _)]
public double Minus(double x, double y) { return x - y; }
А вот описанного мною варианта я не увидел. Можете показать?
P.S. Ну и еще по поводу ANTLR — то, что грамматика определяется отдельным языком дает некоторые, довольно ощутимые преимущества, а именно возможность написать нормальные инструменты работы с этим языком: редактор кода, компилятор с проверкой грамматики на этапе компиляции (тут особенно ценна выдаваемая информация — где именно ошибка), отладчик (кстати, довольно неплохой у ANTLR, правда только для Java, но если не использовать Actions, а только генерировать AST — все равботает для любой среды и языка).
В вашем случае добиться этого, наверное, возможно, но, подозреваю, будет несколько затруднительно.
Здравствуйте, Sucaba, Вы писали:
S>Что такое IronText? S>-------------------
S>IronText — это библиотека для создания DSL и языков программирования под .Net с S>низким уровнем сложности, и в то же время, достаточно мощная для создания любых S>контекстно-свободных языков.
Что со скоростью?
Есть ли парсеры серьезных языков (C#, Java, C, C++, ...)?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Михаил Романов, Вы писали:
МР>Здравствуйте, Sucaba, Вы писали:
S>>В любом случае, идея в том, что вам не нужно думать как прикрутить S>>инструменты вроде ANTLR к вашему проекту.
МР>Да, вроде не так и сложно прикручивается...
Все относительно. Для не очень опытных .Net программистов это явные грабли, а учитывая диагностику (ошибки),
желаемую интеграцию с msbuild и инсталляцию JVM для .Net-разработки, ... в общем, думаю, мысль понятна.
Хотя проблема действительно не приоритетная. В UserGuide так и написано.
МР>Его (ANTLR) главная беда — полученное в результате парсинга AST ни разу не типизированное (точнее там все узлы одного типа), и его дальнейшая обработка довольно муторная задача. Это поведение можно поменять, но предлагаемы для этого методы не слишком удобны.
Вы не учитываете одну очень мощную фичу ANTLR, а иммно Tree Parser. Но, в общем, соглашусь, не
типизированное дерево разбора — это проблема для многих задач.
МР>Как в вашей библиотеке реализуется такой сценарий разбора: исходный текст -> (парсер) -> AST -> (код обработки AST) -> результат. МР>Т.е. говоря коротко — как получить все AST и что оно собой будет представлять.
Хорошая новость в том, что такая функциональность существует:
Вы можете воспользоваться методом Interperter.BuildTree(...). Хотя, строго говоря, результат не является tree (деревом), а более мощной структурой под именем SPPF (Shared Packed Parse Forest). Она поддерживает компактное представление всех альтернатив разбора текста. Если вам интересно, можете глянуть на соответствующий тип SppfNode, который поддерщивает класический Visitor через ISppfNodeVisitor интерфейс.
Плохая новость в том, что классический visitor — это плохой инструмент для разбора нетипизированного дерева.
Для создания типизированного дерева, вам придется реализовать построение дерева в методах. На примере того же
калькулятора, это будет выглядеть так:
[Parse(_, "+", _)]
public Expr Plus(Expr x, Expr y) { return new PlusExpr(x, y); }
[Parse(_, "-", _)]
public Expr Minus(Expr x, Expr y) { return new MinusExpr(x, y); }
...
abstract class Expr { }
class PlusExpr : Expr { }
class MinusExpr : Expr { }
Довольно просто, не так ли? В реальности ситуация немного сложнее, но
есть интересный подход как упростить реализацию для случая когда синтаксис
(parse tree) отличается от (AST). Не буду сейчас останавливаться на этом — лучше
как-нибудь напишу пример.
В будущем же, планируется реализация дерева и его разбора на основе ATerms (на github-е можно глянуть).
МР>В тех примерах, которые я нашел (но может что-то упустил) вся полезная работа зашивается в Actions, которые срабатывают на конкретное синтаксическое правило. МР>Что-то типа такого (это из примера калькулятора): МР>
МР>А вот описанного мною варианта я не увидел. Можете показать?
Вы можете посмотреть DynamicLinq пример. Там в роли AST выступають
Linq Expressions. Пример написан впопыхах (наперед прошу прощения),
но если вы уже писали свой Linq Provider, то тема должна быть для вас
понятна. Еще в роли AST можно исользовать CodeDom, Roslyn.
МР>P.S. Ну и еще по поводу ANTLR — то, что грамматика определяется отдельным языком дает некоторые, довольно ощутимые преимущества, а именно возможность написать нормальные инструменты работы с этим языком: редактор кода, компилятор с проверкой грамматики на этапе компиляции (тут особенно ценна выдаваемая информация — где именно ошибка),
1. Редактор кода у вас есть — VS. Не вижу чего там не хватает
Более того, неужели вы знаете очень много редакторов грамматик с лучшим функционалом чем VS для c#??
2. IronText работает на этапе билда (по-умолчанию) и выдает ошибки о грамматике. Конечно
IronText сыроват по сравнению с Bison и Antlr, но некоторые ошибки в грамматике
он показывает.
3. Что касается места ошибки, то на данном этапе ошибки просто содержат полное имя
класса или метода ответственного за проблему — этого, исходя из моей практики
достаточно. Как правило, такой тип или метод был недавно редактирован, соответственно
открыт в редакторе. Но вы правы — это неудобство, хотя не критическое. Для разрешения
этой проблемы в будущем попробую брать позицию атрибутов из PDB файла через Mono.Cecil.
Не уверен что получиться, но .Net другого решения пока не предоставляет.
MP> отладчик (кстати, довольно неплохой у ANTLR, правда только для Java, но если не использовать Actions, а только генерировать AST — все равботает для любой среды и языка). МР>В вашем случае добиться этого, наверное, возможно, но, подозреваю, будет несколько затруднительно.
Если вы имеете ввиду генерацию парсера для другого языка/платформы, то
дизайн IronText учитывает такую возможность в будущем. Пока не хватает времени
на все задумки, поэтому в версии 1.0 ничего такого не будет.
Проблема в другом: что есть парсер, скажем, для JavaScript? Каким вы видите
результат: нетипизированное дерево разбора или действия связанные с грамматикой?
Если дерево, то как его обрабатывать? Если действия, то где их писать и как привязать
к грамматике?
Будут идеи — пишите. Обсудим, запланируем.
Кстати, добавить в IronText парсинг спецификаций не сложно. Но нужно ли?
Здравствуйте, Sucaba, Вы писали:
S>Каким вы видите результат: нетипизированное дерево разбора или действия связанные с грамматикой? S>Если дерево, то как его обрабатывать? Если действия, то где их писать и как привязать S>к грамматике?
Для языкостроения зачастую важно и то и другое. Пример как можно привязать действия к грамматике (нотация N2):
syntax module Calc
{
using PrettyPrint;
using Outline;
using TokenNames;
using StandardSpanClasses;
using Whitespaces;
using Identifiers;
using CStyleComments;
[StartRule, ExplicitSpaces]
syntax Start = s Expression !Any
{
Value() : double = Expression.Value();
}
extend syntax IgnoreToken
{
| [SpanClass(Comment)] SingleLineComment = SingleLineComment;
| [SpanClass(Comment)] MultiLineComment;
}
token Number = ['0'..'9']+ ('.' ['0'..'9']*)?;
syntax Expression
{
Value() : double;
missing Value = double.NaN;
| Number
{
override Value = double.Parse(GetText(this.Number));
}
| Add = Expression sm '+' sm Expression precedence 10
{
override Value = Expression1.Value() + Expression2.Value();
}
| Sub = Expression sm '-' sm Expression precedence 10
{
override Value = Expression1.Value() - Expression2.Value();
}
| Mul = Expression sm '*' sm Expression precedence 20
{
override Value = Expression1.Value() * Expression2.Value();
}
| Div = Expression sm '/' sm Expression precedence 20
{
override Value = Expression1.Value() / Expression2.Value();
}
| Pow = Expression sm '^' sm Expression precedence 30 right-associative
{
override Value = System.Math.Pow(Expression1.Value(), Expression2.Value());
}
| Neg = '-' Expression precedence 100
{
override Value = -Expression.Value();
}
| Plus = '+' Expression precedence 100
{
override Value = Expression.Value();
}
| Rounds = '(' Expression ')'
{
override Value = Expression.Value();
}
}
}
Использование:
using N2;
using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;
using System;
using System.Collections.Generic;
using System.Console;
using System.Linq;
module Program
{
Main() : void
{
def parserHost = ParserHost();
def loop()
{
Write("input>");
def input = ReadLine();
unless (string.IsNullOrWhiteSpace(input))
{
def source = SingleLineSourceSnapshot(input);
def parseResult = Calc.Start(source, parserHost);
def ast = CalcAstWalkers.Start(parseResult);
WriteLine($"Pretty print: $ast");
unless (parseResult.IsSuccess)
foreach(error in parseResult.GetErrors())
{
def (line, col) = error.Location.StartLineColumn;
WriteLine($<#$line:$col: $(error.Message)#>);
}
def result = ast.Value();
WriteLine($"Result: $result");
loop();
}
}
loop();
}
}
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Sucaba, Вы писали:
S>>Что такое IronText? S>>-------------------
S>>IronText — это библиотека для создания DSL и языков программирования под .Net с S>>низким уровнем сложности, и в то же время, достаточно мощная для создания любых S>>контекстно-свободных языков.
VD>Что со скоростью?
Чтобы ответить, попробую зайти с разных сторон:
1) Подход в стиле абстракционизма:
Сканер очень шустрый. После реализации еще нескольких фич, подозреваю
что конкурентов под .net для него не будет.
Парсер для LALR1 граматик тож, в общем, не плох учитывая что это push-parser
и что уровень поддерживаемых абстракций в коде довольно таки высок.
GLR парсер в несколько раз медленнее. Хотя это закономерно, учитывая сложность
алгоритма и поверхностный уровень оптимизаций.
2) Конкретно из perf.-тестов:
Для грамматики:
S : E;
E : E '+' F | F;
F : 'a' | '(' E ')';
На вход подавался файл содержащий: 'a' ('+' 'a')^1000000 // ~ 1.9 Mb текста.
Для сканнера — это худший вариант, поскольку все терминальные символы
занимають 1 символ и почти все время он тратит на создание токенов, а не
собственно разбор текста.
просто чтение файла = 00:00:00.0466094
scan = 00:00:00.1352407
GLR парсер (на той-же грамматике и том же файле):
parse (recognize) + scan = 00:00:04.2269473
parse (actions) + scan = 00:00:04.6417543
parse (tree) + scan = 00:00:06.9365794
Есть еще perf.-тесты конкретно для GLR и
неоднозначных грамматик, но это скорее попытка
убить алгоритм нежели что-то практическое.
3) Если вы ожидали сравнительные цифры с другими
инструментами, то я не нашел достаточно свежих
и адекватных результатов.
Писать свои тесты для ANTLR, Irony было, простите, откровенно
лень.
4) В данный момент основная цель разработки не скорость, а именно
"вылизывание" алгоритмов и абстракций. Когда проект дойдет
до определенного уровня качества (версии так к 3.0) надеюсь
что некоторые алгоритмы перепишутся с использованием генерации
кода в MSIL. Так как сейчас это сделано в сканере.
VD>Есть ли парсеры серьезных языков (C#, Java, C, C++, ...)?
Есть упрощенная версия MSIL компилятора. Кстати, этот-же c# API
используется для генерации MSIL кода. Но, рапортовать о реализации этого языка
еще рано. Нет поддержки generic и почти нет pinvoke, также там
используються фичи которые еще не обкатаны и не документированы.
Но если вас не воротит от чтения сырого кода, то можете глянуть в
\Src\IronText.Core\Lib\IL\.
Тесты тут: \Src\Sandbox\IronText.Lib.Stem.Tests\IL\ParserTest.cs
MSIL примеры: \Src\Sandbox\IronText.Lib.Stem.Tests\Data\
Кроме этого, лично я, не планирую пока реализовывать серьезный язык программирования (тем боле с++ .
Основная цель сейчас — это поддержка DSL и LOP.
Но лично вам ничто не мешает создать свой PL и заодно подкидывать баги на и идеи IronText github.
Если появятся желание написать такой пример для IronText буду премного благодарен.
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Sucaba, Вы писали:
S>>Каким вы видите результат: нетипизированное дерево разбора или действия связанные с грамматикой? S>>Если дерево, то как его обрабатывать? Если действия, то где их писать и как привязать S>>к грамматике?
H>Для языкостроения зачастую важно и то и другое. Пример как можно привязать действия к грамматике (нотация N2):
H>syntax module Calc
H> ...
Идея ваша понятна. Но, в IronText нет конфликта при выборе дерево или семантические действия.
Дерево берется из Interpreter.BuildTree(...). В этом случае действия связанные с грамматикой
не используются. В случае же Interpreter.Parse(...) выполняються действия-методы.
Кстати, оба способа в IronText представляются одной и той же абтракцией IProducer. Более того, вы можете создать свой producer и строить деревья и выподнять действия такб как вам хочеться.
Но возвращаясь к предыдущему моему посту, кажется проблема была связана с крос-платформеностю
т.е возможностью создать парсер, скажем для JavaScript (не путать с парсером JS). Ваш пример
этой проблемы, как я понимаю, не решает?
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Sucaba, Вы писали:
AVK>Два вопроса: AVK>1) В документации не увидел внятного описания, кто из чего и когда получает. Чисто теоретически предполагаю что схема такая: AVK>
AVK>Исходник на шарпе -> csc.exe -> сборка с грамматикой -> твоя тулза -> вторая сборка с парсером
AVK>
AVK>Я правильно угадал?
Да, именно так.
Но кроме того если IronText.Compiler.dll и Mono.Cecil.*.dll лежат рядом, то вторая сборка з парсером
будет и в рантайме билдится. По первому требованию.
Доку, к сожалению, пока дописываю.
AVK>2) Насколько оно стабильно и оттестировано?
Ответ в "попугаях" давать? Если серьезно, то тестов много на каждый чих.
Но насчет полного отсутствия багов и проблем, то это из области фантастики.
Все видимые толстые баги поправлены, если что проопустил — говорите.
Функциональнось как и документация еще не вся. В основном, не хватает продвинутой
обработки ошибок. В общем классическая бета-версия для публичного рассмотрения.
Здравствуйте, Sucaba, Вы писали:
S>В основном, не хватает продвинутой S>обработки ошибок. В общем классическая бета-версия для публичного рассмотрения.
А какая сейчас есть?
И что с восстановлением после обнаружения ошибок?
ЗЫ
Вообще, о серьезном тестировании парсера можно вести речь когда на нем реализована хотя бы одна грамматика настоящего языка программирования. Калькулторы и прочая мелочь не способны выявить всех проблем. Так что советую тебе создать, например, грамматику C#. Это можно сделать адаптировав имеющиеся (в большом количестве) грамматики.
Тогда можно будет и о скорости парсера серьезно рассуждать, и о качестве восстановления после обнаружения ошибок, и о прочих потребительских качествах.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Sucaba, Вы писали:
S>>В основном, не хватает продвинутой S>>обработки ошибок. В общем классическая бета-версия для публичного рассмотрения.
VD>А какая сейчас есть? VD>И что с восстановлением после обнаружения ошибок?
Сейчас восстановление после ошибок состоит из двух фаз (классика):
— локальная коррекция — это попытка исправить ситуацию через вставку/удаление токенов
в районе проблемного токена
— "panic-mode" — это, грубо говоря, удаление уже разобраных выражений и пропуск проблемных
терминальных символов пока парсер не сможет заработать.
Чего не хватает (коротко):
— еще одной фазы "Scope Recovery" — это автоматическое нахождение
парных элементов вроде "( ... )", "begin ... end" в грамматике и
попытка восстановления из ошибки через добавление закрывающего элемента
с соответствующим сообщением.
— В локальной коррекции не хватает:
— исправление ключевого слова через коррекцию символов (spell-correction).
например: whle, pulbic.
— склейка двух соседних токенов (например: wh ile, pu blic)
— разделение токена на два (например intmyvariable).
— возможность пользователю как-то изменять логику коррекции (?)
— Сейчас локальная коррекция вставляет любой подходящий токен, что
выглядит не очень красиво, но это не критично.
VD>ЗЫ
VD>Вообще, о серьезном тестировании парсера можно вести речь когда на нем реализована хотя бы одна грамматика настоящего языка программирования. Калькулторы и прочая мелочь не способны выявить всех проблем. Так что советую тебе создать, например, грамматику C#. Это можно сделать адаптировав имеющиеся (в большом количестве) грамматики. VD>Тогда можно будет и о скорости парсера серьезно рассуждать, и о качестве восстановления после обнаружения ошибок, и о прочих потребительских качествах.
Как я уже сказал, я работаю над парсером MSIL. Это и есть тест большого языка, заодно и нужная
вещь для проекта.
Но вообще, утверждение о том, что тестировать можно только на очень больших языках очень
поверхностно. Например, что вам скажет скорость работы c# парсера если вы хотите написать
парсер лога? Ответ: ничего. Тестировать нужно конкретные вещи, а не "что-то большое и ужасное".
С другой стороны, реализация больших и сложных практических языков может выявить упущенные
проблемы. И после их идентификации придется писать конкретные тесты которые бы показали
что проблема решена для всех языков.
На данный момент проект находится на стадии бета и я никоим образом не хочу сказать что
он на 100% подходит для написания парсера для c#. Вы правы, я этого не знаю. Но, что
вам, VladD2, мешает сделать такую реализацию для себя или даже для примеров в проекте?
Цель бета версии как раз и состоит в испытании на практике!
Здравствуйте, Sucaba, Вы писали:
S>Но кроме того если IronText.Compiler.dll и Mono.Cecil.*.dll лежат рядом, то вторая сборка з парсером S>будет и в рантайме билдится. По первому требованию.
Неявно? Или все таки есть возможность явно не тащить в рантайм вообще никакого функционала, связанного с генерацией парсеров?
AVK>>2) Насколько оно стабильно и оттестировано? S>Ответ в "попугаях" давать? Если серьезно, то тестов много на каждый чих.
Тесты это понятно. Вопрос в другом — есть ли релизные коммерческие проекты, которые его используют или пока что идет активная разработка?
S>В общем классическая бета-версия для публичного рассмотрения.
Понятно.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, Sucaba, Вы писали:
S>Как я уже сказал, я работаю над парсером MSIL.
В смысле? MSIL же бинарный с тривиальной структурой, чего там парсить то? Или ты имеешь в виду IL Assembler? Так он же очень примитивный, там и парсить то особо нечего.
S>поверхностно. Например, что вам скажет скорость работы c# парсера если вы хотите написать S>парсер лога?
Парсер лога??? Я что то не припоминаю ни одного лога, который нельзя было бы отпарсить регексом. Т.е. это ты только лексер протестируешь. А уж GLR на фоне этого, как термоядерная бомба на фоне травматического пистолета.
S>На данный момент проект находится на стадии бета и я никоим образом не хочу сказать что S>он на 100% подходит для написания парсера для c#. Вы правы, я этого не знаю. Но, что S>вам мешает сделать такую реализацию для себя или даже для примеров в проекте?
Он просто хочет померяться длиной своей Нитры, не переживай
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали: S>>Но кроме того если IronText.Compiler.dll и Mono.Cecil.*.dll лежат рядом, то вторая сборка з парсером S>>будет и в рантайме билдится. По первому требованию. AVK>Неявно? Или все таки есть возможность явно не тащить в рантайм вообще никакого функционала, связанного с генерацией парсеров?
Еще раз, есть два варианта (на ваше усмотрение):
1) Тот который вы назвали. В рантайме нет никакого билда, генерация .Derived.dll через msbuild.
2) Ленивый билд по первому требованию языка/парсера. В этом случае в рантайме работает генератор,
и соответственно IronText.Compiler.dll и Mono.Cecil.*.dll дожны быть рядом с вашим dll.
Все примеры работают по 1. Более того, для релиза вы можете склеить ваш DLL с
.Derived.dll c помощью MergeDerived.exe:
$> <nuget-package-path>\tools\net40\MergeDerived.exe <full-path-to-your dll>
AVK>Тесты это понятно. Вопрос в другом — есть ли релизные коммерческие проекты, которые его используют или пока что идет активная разработка?
Я сделал анонс проекта вчера утром. Вряд ли кто-то уже успел сделать релизный коммерческий проект