C # для XML или префиксной нотации

#c# #compiler-construction #programming-languages #export-to-xml

#c# #построение компилятора #программирование-языки #экспорт в xml

Вопрос:

Может быть, это своего рода мечта / вопрос о пироге на лыжах. Кто-нибудь знает инструмент, который будет создавать XML или префиксную нотацию (lispy) — который включает комментарии к документации из исходного кода C #? Похоже, это было бы полезно для ряда генераторов документации, или инструментов статического анализа, или чего-то еще.

По общему признанию, это инструмент среднего уровня, и, вероятно, его можно выполнить с помощью компилятора-генератора, такого как Antlr. Однако, кто-то, возможно, поцарапал зуд и создал что-то в этом роде … а?

Редактировать: для уточнения: «это включает комментарии к документации из исходного кода C #»

Я добавляю это, чтобы отличить, что AST, вероятно, не будет включать комментарии (хотя Antlr имеет концепцию «канала», которая может передавать комментарии).

Редактировать: что касается того, что нужно извлечь: ну, в основном AST, с комментариями, но в форме, которую можно использовать повторно, т. Е. Lispy или XML было бы хорошо. Но это должно быть завершено, чтобы, если для одного повторного назначения не нужна информация, другой процесс все равно мог извлечь выгоду из ее включения.

Надеюсь, это поможет.

L-

Комментарии:

1. Если вы можете выполнять такие преобразования из источника в источник, у вас уже есть синтаксический анализатор и AST. Почему бы просто не использовать это в инструментах, которые вы собираетесь использовать в качестве потребителя, вместо того, чтобы они проходили через такое представление?

2. Не могли бы вы уточнить, какую информацию вы хотите извлечь, возможно, предоставив простой пример ввода и вывода?

Ответ №1:

Этот зуд был давно устранен.

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

Смотрите пример ниже, в котором исходный код анализируется DMS в AST с комментариями (до и после), украшающими различные узлы AST, а затем сбрасывается в выходной поток в синтаксисе «Lispy». Также существует тривиальный вариант XML, просто чтобы удовлетворить тех людей, которые должны иметь XML.

Как правило, пользователи DMS используют это только для просмотра деревьев синтаксического анализа, потому что DMS предоставляет огромное количество механизмов для анализа, преобразования и печати (регенерации текста, включая комментарии, из AST).

Было бы довольно тривиально использовать DMS для обхода AST и выбора только тех комментариев, которые удовлетворяли любым критериям, которые вы пожелали, включая «выглядит как комментарий к документации». Что еще более важно, вы также получаете точную информацию о местоположении источника, а также доступ к дереву, к которому прикреплен комментарий; вы можете легко создавать сводки методов из поддерева заголовка метода.

Большинство пользователей DMS хотят делать более сложные вещи, которые, как мы утверждаем, гораздо проще выполнять в DMS, используя все оборудование, предоставляемое DMS, чем экспортировать в какой-либо специальный инструмент в формате XML или Lisp, где вам придется заново изобретать все это оборудование. снова.

Для этого кода:

 /* MyClass source file
   Contains MyClass and its methods
*/
class MyClass {

   static int count; // counts number of class instances

   MyClass() { count  ; // bump instance count
     }

   /* First Method */
   get_count() { return count; }

}
  

Анализатор C # DMS выдает этот вывод (обратите внимание на встроенные комментарии):

 Domain Parser for CSharp~CSharp4_0 2.3.3
Copyright (C) Semantic Designs 1996-2010; All Rights Reserved
Parsing Time: 0.001728 seconds
(compilation_unit@CSharp~CSharp4_0=1#58e66c0^0 Line 4 Column 1 File C:/temp/test.cs
 (extern_alias_directives@CSharp~CSharp4_0=2#58e3340 Line 4 Column 1 File C:/temp/test.cs)extern_alias_directives
 (using_directives@CSharp~CSharp4_0=493#58e3380 Line 4 Column 1 File C:/temp/test.cs)using_directives
 (global_attributes@CSharp~CSharp4_0=1008#58e33c0 Line 4 Column 1 File C:/temp/test.cs)global_attributes
 (namespace_member_declarations@CSharp~CSharp4_0=506#58e6440 Line 4 Column 1 File C:/temp/test.cs
  (namespace_member_declarations@CSharp~CSharp4_0=505#58e3400 Line 4 Column 1 File C:/temp/test.cs)namespace_member_declarations
  (namespace_member_declaration@CSharp~CSharp4_0=516#58e3dc0 Line 4 Column 1 File C:/temp/test.cs
   (class_declaration@CSharp~CSharp4_0=533#58e6280 Line 4 Column 1 File C:/temp/test.cs
   |(class_header@CSharp~CSharp4_0=526#58e3600 Line 4 Column 1 File C:/temp/test.cs
   | precomment 4:1 `/* MyClass source file

   Contains MyClass and its methods

*/'
   | (attributes@CSharp~CSharp4_0=1023#58e3440 Line 4 Column 1 File C:/temp/test.cs)attributes
   | (class_modifiers@CSharp~CSharp4_0=534#58e3480 Line 4 Column 1 File C:/temp/test.cs)class_modifiers
   | (optional_partial@CSharp~CSharp4_0=524#58e34c0 Line 4 Column 1 File C:/temp/test.cs)optional_partial
   | (identifier@CSharp~CSharp4_0=1106#58e3580 Line 4 Column 7 File C:/temp/test.cs
   |  (IDENTIFIER@CSharp~CSharp4_0=1171#58e3500[`MyClass'] Line 4 Column 7 File C:/temp/test.cs)IDENTIFIER
   | )identifier
   | (class_base@CSharp~CSharp4_0=552#58e35c0 Line 4 Column 15 File C:/temp/test.cs)class_base
   |)class_header
   |(class_member_declarations@CSharp~CSharp4_0=563#58e3c80 {3} Line 6 Column 4 File C:/temp/test.cs
   | (class_member_declaration@CSharp~CSharp4_0=573#58e3ce0 Line 6 Column 4 File C:/temp/test.cs
   |  (field_declaration@CSharp~CSharp4_0=591#58e3e00 Line 6 Column 4 File C:/temp/test.cs
   |   postcomment 5:1 `// counts number of class instances'
   |   (attributes@CSharp~CSharp4_0=1023#58e3300 Line 6 Column 4 File C:/temp/test.cs)attributes
   |   (field_modifiers@CSharp~CSharp4_0=593#58e3aa0 {1} Line 6 Column 4 File C:/temp/test.cs
   |   |(field_modifier@CSharp~CSharp4_0=607#58e3840 Line 6 Column 4 File C:/temp/test.cs)field_modifier
   |   )field_modifiers
   |   (integral_type@CSharp~CSharp4_0=42#58e3540 Line 6 Column 11 File C:/temp/test.cs)integral_type
   |   (variable_declarators@CSharp~CSharp4_0=104#58e3780 Line 6 Column 15 File C:/temp/test.cs
   |   |(variable_declarator@CSharp~CSharp4_0=112#58e38a0 Line 6 Column 15 File C:/temp/test.cs
   |   | (identifier@CSharp~CSharp4_0=1106#58e3d00 Line 6 Column 15 File C:/temp/test.cs
   |   |  (IDENTIFIER@CSharp~CSharp4_0=1171#58e3460[`count'] Line 6 Column 15 File C:/temp/test.cs)IDENTIFIER
   |   | )identifier
   |   |)variable_declarator
   |   )variable_declarators
   |  )field_declaration
   | )class_member_declaration
   | (class_member_declaration@CSharp~CSharp4_0=579#58e6580 Line 8 Column 4 File C:/temp/test.cs
   |  (constructor_declaration@CSharp~CSharp4_0=798#58e61a0 Line 8 Column 4 File C:/temp/test.cs
   |   (constructor_header@CSharp~CSharp4_0=792#58e6720 Line 8 Column 4 File C:/temp/test.cs
   |   |(attributes@CSharp~CSharp4_0=1023#58e38c0 Line 8 Column 4 File C:/temp/test.cs)attributes
   |   |(constructor_modifiers@CSharp~CSharp4_0=800#58e3b40 Line 8 Column 4 File C:/temp/test.cs)constructor_modifiers
   |   |(constructor_declarator@CSharp~CSharp4_0=815#58e3760 Line 8 Column 4 File C:/temp/test.cs
   |   | (identifier@CSharp~CSharp4_0=1106#58e3d40 Line 8 Column 4 File C:/temp/test.cs
   |   |  (IDENTIFIER@CSharp~CSharp4_0=1171#58e3d80[`MyClass'] Line 8 Column 4 File C:/temp/test.cs)IDENTIFIER
   |   | )identifier
   |   | (optional_formal_parameter_list@CSharp~CSharp4_0=647#58e6700 Line 8 Column 12 File C:/temp/test.cs)optional_formal_parameter_list
   |   | (constructor_initializer@CSharp~CSharp4_0=816#58e37c0 Line 8 Column 14 File C:/temp/test.cs)constructor_initializer
   |   |)constructor_declarator
   |   )constructor_header
   |   (block@CSharp~CSharp4_0=405#58e6780 Line 8 Column 14 File C:/temp/test.cs
   |   |(statement_list@CSharp~CSharp4_0=406#58e3d20 Line 8 Column 16 File C:/temp/test.cs
   |   | (non_pp_embedded_statement@CSharp~CSharp4_0=367#58e39a0 Line 8 Column 16 File C:/temp/test.cs
   |   |  postcomment 2:1 `// bump instance count'
   |   |  (statement_expression@CSharp~CSharp4_0=433#58e6540 Line 8 Column 16 File C:/temp/test.cs
   |   |   (primary_no_array_creation_expression@CSharp~CSharp4_0=160#58e6740 Line 8 Column 16 File C:/temp/test.cs
   |   |   |(identifier@CSharp~CSharp4_0=1106#58e3800 Line 8 Column 16 File C:/temp/test.cs
   |   |   | (IDENTIFIER@CSharp~CSharp4_0=1171#58e3700[`count'] Line 8 Column 16 File C:/temp/test.cs)IDENTIFIER
   |   |   |)identifier
   |   |   )primary_no_array_creation_expression
   |   |  )statement_expression
   |   | )non_pp_embedded_statement
   |   |)statement_list
   |   )block
   |  )constructor_declaration
   | )class_member_declaration
   | (class_member_declaration@CSharp~CSharp4_0=579#58e6220 Line 12 Column 4 File C:/temp/test.cs
   |  (constructor_declaration@CSharp~CSharp4_0=798#58e3a80 Line 12 Column 4 File C:/temp/test.cs
   |   (constructor_header@CSharp~CSharp4_0=792#58e6380 Line 12 Column 4 File C:/temp/test.cs
   |   |(attributes@CSharp~CSharp4_0=1023#58e3a00 Line 12 Column 4 File C:/temp/test.cs)attributes
   |   |(constructor_modifiers@CSharp~CSharp4_0=800#58e38e0 Line 12 Column 4 File C:/temp/test.cs)constructor_modifiers
   |   |(constructor_declarator@CSharp~CSharp4_0=815#58e36e0 Line 12 Column 4 File C:/temp/test.cs
   |   | (identifier@CSharp~CSharp4_0=1106#58e3a20 Line 12 Column 4 File C:/temp/test.cs
   |   |  (IDENTIFIER@CSharp~CSharp4_0=1171#58e6760[`get_count'] Line 12 Column 4 File C:/temp/test.cs
   |   |   precomment 0:1 `/* First Method */')IDENTIFIER
   |   | )identifier
   |   | (optional_formal_parameter_list@CSharp~CSharp4_0=647#58e6960 Line 12 Column 14 File C:/temp/test.cs)optional_formal_parameter_list
   |   | (constructor_initializer@CSharp~CSharp4_0=816#58e65a0 Line 12 Column 16 File C:/temp/test.cs)constructor_initializer
   |   |)constructor_declarator
   |   )constructor_header
   |   (block@CSharp~CSharp4_0=405#58e6200 Line 12 Column 16 File C:/temp/test.cs
   |   |(statement_list@CSharp~CSharp4_0=406#58e6160 Line 12 Column 18 File C:/temp/test.cs
   |   | (non_pp_embedded_statement@CSharp~CSharp4_0=373#58e3e60 Line 12 Column 18 File C:/temp/test.cs
   |   |  (null_coalescing_expression@CSharp~CSharp4_0=327#58e3e40 Line 12 Column 25 File C:/temp/test.cs
   |   |   (conditional_or_expression@CSharp~CSharp4_0=325#58e3ec0 Line 12 Column 25 File C:/temp/test.cs
   |   |   |(conditional_and_expression@CSharp~CSharp4_0=323#58e6a00 Line 12 Column 25 File C:/temp/test.cs
   |   |   | (inclusive_or_expression@CSharp~CSharp4_0=321#58e3c00 Line 12 Column 25 File C:/temp/test.cs
   |   |   |  (exclusive_or_expression@CSharp~CSharp4_0=319#58e3b20 Line 12 Column 25 File C:/temp/test.cs
   |   |   |   (and_expression@CSharp~CSharp4_0=317#58e35a0 Line 12 Column 25 File C:/temp/test.cs
   |   |   |   |(equality_expression@CSharp~CSharp4_0=314#58e6520 Line 12 Column 25 File C:/temp/test.cs
   |   |   |   | (additive_expression@CSharp~CSharp4_0=300#58e6140 Line 12 Column 25 File C:/temp/test.cs
   |   |   |   |  (multiplicative_expression@CSharp~CSharp4_0=296#58e6460 Line 12 Column 25 File C:/temp/test.cs
   |   |   |   |   (primary_no_array_creation_expression@CSharp~CSharp4_0=160#58e63a0 Line 12 Column 25 File C:/temp/test.cs
   |   |   |   |   |(identifier@CSharp~CSharp4_0=1106#58e37e0 Line 12 Column 25 File C:/temp/test.cs
   |   |   |   |   | (IDENTIFIER@CSharp~CSharp4_0=1171#58e6560[`count'] Line 12 Column 25 File C:/temp/test.cs)IDENTIFIER
   |   |   |   |   |)identifier
   |   |   |   |   )primary_no_array_creation_expression
   |   |   |   |  )multiplicative_expression
   |   |   |   | )additive_expression
   |   |   |   |)equality_expression
   |   |   |   )and_expression
   |   |   |  )exclusive_or_expression
   |   |   | )inclusive_or_expression
   |   |   |)conditional_and_expression
   |   |   )conditional_or_expression
   |   |  )null_coalescing_expression
   |   | )non_pp_embedded_statement
   |   |)statement_list
   |   )block
   |  )constructor_declaration
   | )class_member_declaration
   |)class_member_declarations
   |(optional_semicolon@CSharp~CSharp4_0=959#58e3b60 Line 16 Column 1 File C:/temp/test.cs)optional_semicolon
   )class_declaration
  )namespace_member_declaration
 )namespace_member_declarations
)compilation_unit
Exiting with final status 0
  

Комментарии:

1. Потрясающе. Прямо сейчас меня бы заинтересовали AST для JavaScript и C #, если это возможно. Какой из многих инструментов, которые у вас есть, делает это для приведенного выше примера? Можно ли запустить его из командной строки? Я бы предпочел не писать специальные инструменты, но факт в том, что я хочу обычно помещать что-то в конвейер сборки, и это работает лучше, если этот инструмент не является огромной IDE или чем-то в этом роде.

2. DMS генерирует инструменты, которые в основном управляются командной строкой, потому что большинство применений, даже ваше, как правило, являются частью более крупной сборки. Сгенерированный анализатор C # для DMS был вызван с помощью этой командной строки: «запустите DomainParser AST C:/temp/test.cs » чтобы получить результат, который вы видите здесь. Да, есть интерфейс JavaScript, который работает точно так же, с точно такой же возможностью захвата комментариев.

Ответ №2:

Хорошо, теперь ясно, что вам нужен полный AST, в стандартных инструментах MS пока ничего нет. Однако команда компиляторов C # в настоящее время работает над «Roslyn», он же «компилятор как сервис». Предварительные сборки должны появиться очень скоро — и в этот момент должно стать яснее, поддерживает ли это то, что вам нужно.

На данный момент неизвестно, будет ли Roslyn доступен только как часть .NET framework или будет ли он поставляться только с некоторыми артикулами Visual Studio — но вполне может оказаться более доступным, чем некоторые другие альтернативы.


Оригинальный ответ

Это уже часть языка и обычных инструментов — в Visual Studio просто перейдите в раздел Свойства проекта / Сборка / Вывод и установите флажок с «Файлом документации XML». Выберите файл для записи документов и вперед.

Построение читаемого HTML из этого немного сложнее; Sandcastle сделает это, но для этого нужен вспомогательный проект — конструктор файлов справки Sandcastle, чтобы превратить его в более управляемую задачу. Однако он довольно гибок в том, что он создает — для примера вы можете посмотреть документацию API для Noda Time, которая генерируется с помощью Sandcastle .

Кроме того, если вы создаете библиотеку классов для использования другими пользователями, если вы отправляете XML вместе с DLL и у него то же имя (только с суффиксом .xml вместо .dll), Visual Studio будет использовать его для предоставления всплывающих подсказок вашим пользователям при использовании ваших типов, методов и т. Д.

Комментарии:

1. Кажется, это извлекает только документацию / комментарии. Похоже, что OP думает об экспорте представления всего исходного кода (см. Ссылку на Инструменты статического анализа).

2. @delnan: Если это так, то это очень плохо сформулированный вопрос: «который включает комментарии к документации из исходного кода C #» звучит для меня как комментарии XML. Даже если такая вещь существует, я думаю, что придерживаться документации XML имело бы больше смысла.

3. Ну, я предполагаю, что «включает» не существует для этого, но подразумевает, что результат должен включать в себя больше, чем «комментарии к документации из исходного кода C #». Но, честно говоря, я бы тоже не стал делать ставку на это. Да, вопрос не очень ясен, надеюсь, OP сможет прояснить.

4. Добавлены некоторые комментарии с разъяснениями.

5. @lucidquiet: до сих пор не ясно, что вам нужно, кроме комментариев к документации XML из C #. Это комментарии, которые разработчик решил считать документацией. Такие комментарии, как «Нужно обойти ошибку в методе, который я вызываю …», на самом деле не относятся к документации для этого кода, не так ли?

Ответ №3:

Самое близкое, что я знаю, это Sandcastle. Он использует XML в качестве промежуточного вывода и обрабатывает его с помощью XSLT для создания документации в стиле HTML поверх управляемых сборок. Должно быть довольно легко извлечь из него только XML-данные.