c#到XML或前缀表示法

本文关键字:表示 前缀 XML | 更新日期: 2023-09-27 18:10:41

也许这是一个不切实际的问题。有没有人知道有什么工具可以生成XML或前缀表示法(lispy)——其中包括c#源代码中的文档注释?这似乎对许多文档生成器、静态分析工具或其他工具都很有用。

无可否认,这是一种中间件类型的工具,可能可以通过像Antlr这样的编译器生成器来完成。然而,有人可能会挠痒,并产生一些类似的东西……是吗?

编辑:澄清:"包含c#源代码的文档注释"

我添加这个是为了区分AST可能不包含注释(尽管Antlr有一个可以传输注释的"通道"概念)。

编辑:至于要提取什么:基本上是带有注释的AST,但采用可重用的形式,如Lispy或XML就可以了。但它必须是完整的,这样如果一个重新用途不需要信息,另一个进程仍然可以从它的包含中受益。

希望对你有帮助。

L -

c#到XML或前缀表示法

那痒早就挠过了。

我们的源到源程序转换工具,DMS软件重构工具包可以为许多语言做这件事,包括使用DMS的c#前端的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; }
}

DMS的c#解析器产生如下输出(注意内嵌注释):

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

好了,现在很清楚您想要一个完整的AST, MS 的标准工具中还没有。然而,c#编译器团队目前正在致力于"Roslyn",也就是"编译器即服务"。预览版本很快就会发布——到那时,它是否支持你想要的东西就会变得更清楚了。

目前还不知道Roslyn是否会作为。net框架的一部分可用,或者它是否只会与Visual Studio的一些sku一起发布,但它最终可能比其他一些替代品更实惠。


原始回答

这已经是语言和正常工具的一部分-在Visual Studio中,只需进入项目属性/构建/输出并启用"XML文档文件"复选框。选择要写入文档的文件,然后离开。

构建可读的HTML稍微有点棘手;Sandcastle将做到这一点,但需要一个辅助项目- Sandcastle帮助文件生成器将其变成一个更易于管理的任务。它在生成的东西上是相当灵活的——例如,你可以看看Noda Time的API文档,它是由Sandcastle生成的。

另外,如果你正在构建一个供其他人使用的类库,如果你将XML与DLL一起发布,并且它具有相同的名称(只是使用。XML后缀而不是。DLL), Visual Studio将使用它来为用户提供工具提示,当他们使用你的类型,方法等

我所知道的最接近的东西是Sandcastle。它使用XML作为中间输出,并用XSLT对其进行处理,从而在托管程序集上创建html风格的文档。从中获取XML数据应该很容易。