Перевести код C# на AST?

Возможно ли в настоящее время перевести код C# в абстрактное синтаксическое дерево?

Изменить: некоторые разъяснения; Я не обязательно ожидаю, что компилятор сгенерирует для меня AST - парсер подойдет, хотя я бы хотел использовать что-то "официальное". К сожалению, лямбда-выражений недостаточно, поскольку они не позволяют мне использовать тела операторов, что я и ищу.

12 ответов

Решение

Проект Roslyn находится в Visual Studio 2010 и, помимо прочего, предоставляет программный доступ к дереву синтаксиса.

SyntaxTree tree = SyntaxTree.ParseCompilationUnit(
    @" C# code here ");
var root = (CompilationUnitSyntax)tree.Root;

Возможно ли в настоящее время перевести код C# в абстрактное синтаксическое дерево?

Да, тривиально в особых обстоятельствах (= с использованием новой платформы выражений):

// Requires 'using System.Linq.Expressions;'
Expression<Func<int, int>> f = x => x * 2;

Это создает дерево выражений для лямбды, то есть функцию, принимающую int и возвращая дубль. Вы можете изменить дерево выражений, используя каркас Expressions (= классы из этого пространства имен), а затем скомпилировать его во время выполнения:

var newBody = Expression.Add(f.Body, Expression.Constant(1));
f = Expression.Lambda<Func<int, int>>(newBody, f.Parameters);
var compiled = f.Compile();
Console.WriteLine(compiled(5)); // Result: 11

Обратите внимание, что все выражения являются неизменными, поэтому они должны быть построены заново по составу. В этом случае я добавил 1.

Обратите внимание, что эти деревья выражений работают только с реальными выражениями, то есть с контентом, найденным в функции C#. Таким образом, вы не можете получить синтаксические деревья для более высоких конструкций, таких как классы. Используйте платформу CodeDom для них.

Проверьте поддержку.NET CodeDom. Существует старая статья о проекте кода для синтаксического анализатора C# CodeDOM, но он не поддерживает новые языковые функции.

Также предполагается, что в #develop есть поддержка для генерации дерева CodeDom из исходного кода C# согласно этой публикации.

Существует гораздо более мощный, чем проект R#. Nemerle.Peg:

https://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/

И у него есть C# Parser, который анализирует весь код C# и переводит его в AST!

https://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/csharp-parser/

Вы можете скачать установщик здесь: https://code.google.com/p/nemerle/

Лично я бы использовал NRefactory, которая является бесплатной, с открытым исходным кодом и набирает популярность.

ANTLR Parser Generator имеет грамматику для C# 3.0, которая охватывает все, кроме синтаксиса LINQ.

Похоже, что этот вид функциональности будет включен во все, что будет после C# 4, согласно видео PDC Андерса Хейлсберга "Будущее C#".

ANTLR не очень полезен. LINQ не то, что вы хотите.

Попробуйте Mono.Cecil! http://www.mono-project.com/Cecil

Он используется во многих проектах, включая NDepend! http://www.ndepend.com/

Я только что ответил в другом потоке здесь, в Stackru, решение, в котором я реализовал API для создания и управления AST из исходного кода C#

Наш интерфейс C# для DMS анализирует полный C# 3.0, включая LINQ, и производит AST. DMS на самом деле представляет собой экосистему для анализа / преобразования исходного кода с использованием AST для входных языков, предоставляемых интерфейсом.

РЕДАКТИРОВАНИЕ 10/10/2010:... Теперь обрабатывает полный C# 4.0

РЕДАКТИРОВАТЬ: 27.06.2014: Обрабатывает C# 5.0, так как довольно давно.

РЕДАКТИРОВАТЬ: 15.06.2016: Ручки C# 6.0. См. https://stackru.com/a/37847714/120163 для примера AST.

Странно, что никто не предложил взломать существующий компилятор Mono C#.

Пожалуйста, смотрите проект R# (извините, документы на русском языке, но есть несколько примеров кода). Это позволяет манипуляции AST на коде C#.

http://www.rsdn.ru/projects/rsharp/article/rsharp_mag.xml

SVN проекта находится здесь: (URL обновлен, спасибо, derigel)

Также, пожалуйста, смотрите язык Nemerle. Это язык.Net с сильной поддержкой метапрограммирования.

Другие вопросы по тегам