语言服务分析器和扫描仪 (托管包结构)

该分析器是语言服务的焦点。 托管包框架 (MPF)切换需要一个语言分析器选择有关突出显示的代码的信息。 分析器将文本添加到词法标记通过类型和函数然后标识这些标记。

讨论

下面是 C# 方法。

namespace MyNamespace
{
    class MyClass
    {
        public void MyFunction(int arg1)
        {
            int var1 = arg1;
        }
    }
}

在此示例中,标记是单词和标点符号。 此标记如下所示。

标记名称

标记类型

命名空间中,类,公共的,无效, int

keyword

=

operator

{ } ( ) ;

分隔符

MyNamespace, MyClass, MyFunction, arg1, var1

identifier

MyNamespace

命名空间

MyClass

class

MyFunction

方法

arg1

参数

var1

局部变量

该分析器的角色是标识标记。 某些标记可以有多个类型。 在该分析器标识标记后,语言服务可以使用这些信息来提供有用的功能,比如语法匹配显示,和格式 " IntelliSense 操作。

分析器的类型

语言服务分析器与分析器用作编译器一部分。 但是,这种分析程序需要与编译器分析器的方式使用扫描仪和分析器,。

  • 扫描仪用于标识标记的类型。 此信息用于显示的语法和进行快速确定可能触发其他操作,例如,括号匹配标记类型。 此扫描仪由 IScanner 接口表示。

  • 分析器用于描述标记的功能和大小。 此信息可用于 IntelliSense 操作标识语言元素,例如方法,变量、参数和说明,因此,提供列出成员和基于上下文的方法签名。 此分析器还用于设置匹配的语言元素对,例如大括号和括号。 此分析器通过在 LanguageService 类的 ParseSource 方法来访问。

如何实现一个扫描仪和分析器的语言服务由您决定。 多个资源可用的一些描述分析器如何工作方式以及编写拥有分析器。 此外,一些可用和对象可帮助创建分析器。

ParseSource 分析器

不同于用作编译器的一部分分析器 (其中标记将转换为可执行代码的某种形式),语言服务分析器调用可用于许多不同的原因以及许多不同的上下文。 您如何在 ParseSource 方法的此方法在 LanguageService 类由您决定。 请务必谨记 ParseSource 方法可能在后台线程。

警告

ParseRequest 结构包含对 IVsTextView 对象。此 IVsTextView 对象不能在后台线程。实际上,许多基础 MPF 类不能用于后台线程。其中包括 SourceViewFilterCodeWindowManager 类和与视图直接或间接通信的其他类。

此分析程序通常分析整个源文件,首次调用或,当给定时 Check 的分析原因值。 对的后续调用到 ParseSource 方法处理每分析代码的小部分,且可以通过使用结果以前的完整快速分析操作。 ParseSource 方法通过 AuthoringSinkAuthoringScope 对象将分析操作的结果。 AuthoringSink 对象用于收集特定分析原因的信息,例如,有关具有匹配的大括号或方法签名大小的信息参数列表。 AuthoringScope 提供声明和方法签名的集合并为转到支持高级编辑器选项 (转到定义转到声明转到引用)。

IScanner 扫描仪

您还必须实现的扫描仪实现 IScanner。 但是,在中,因为此扫描仪通过 Colorizer 类对一个逐行的基础,实现通常更为方便。 在每行的开头, MPF 为 Colorizer 类的一个值作为传递给扫描程序状态变量。 在每一行末尾,扫描程序返回更新状态变量。 MPF 缓存每行的此状态信息,以便扫描程序可以启动分析从所有行,而不必在源文件开头启动。 一行中本快速扫描允许编辑器提供快速反馈给用户。

分析匹配的大括号的

此示例演示控制流匹配的用户键入的一个右大括号。 在此过程中,为着色使用或用于确定标记的类型的扫描仪,并且该标记是否可以触发与大括号操作。 如果找到该触发器, ParseSource 方法调用查找匹配的大括号。 最后,两个大括号显示。

即使大括号用于触发器的名称并分析原因,此过程不限于实际大括号。 任何对字符指定相对于支持的属性。 示例包括 (和), AMP_LT 和 AMP_GT,和 [] 和。

假定,语言服务支持匹配的大括号。

  1. 用户键入一个结束大括号 (})。

  2. 大括号被插入到光标在源文件,并一个以推进游标。

  3. Source 类的 OnCommand 方法调用与该类型化右大括号。

  4. OnCommand 方法调用。 Source 类的 GetTokenInfo 方法获取该标记在当前光标位置之前的位置。 此标记对应于所键入的右大括号)。

    1. GetTokenInfo 方法调用。 Colorizer 对象的 GetLineInfo 方法获取在当前行的所有标记。

    2. GetLineInfo 方法调用。 IScanner 对象的 SetSource 方法与当前行的文本。

    3. GetLineInfo 方法重复调用 IScanner 对象的 ScanTokenAndProvideInfoAboutIt 方法收集与当前行的所有标记。

    4. GetTokenInfo 方法在从 GetLineInfo 方法获取的标记列表调用 Source 类的私有方法获取包含所需位置的标记,并通过。

  5. OnCommand 方法查找 MatchBraces 一个标记触发器标志。 GetTokenInfo 从方法返回的标记的;即一个右大括号) 的标记。

  6. 如果找到 MatchBraces 触发器标志,在 Source 类的 MatchBraces 方法调用。

  7. MatchBraces 方法以 HighlightBraces的分析原因值的分析操作。 此操作最终调用 LanguageService 类的 ParseSource 方法。 异步分析有效,则在后台线程上调用方法 ParseSource 发生。

  8. 在分析操作完成时,内部完成处理程序 (也称为回调方法) 名为 HandleMatchBracesResponse 在 Source 类调用。 这称为自动提交由 LanguageService 基类,不受分析程序。

  9. HandleMatchBracesResponse 方法获取范围列表中 ParseRequest 对象中存储的 AuthoringSink 对象的。 (范围是在源文件指定线条和字符范围。) 的 TextSpan 结构此列表范围通常包含两个范围,每个打开的和右大括号。

  10. HandleBracesResponse 方法调用在 ParseRequest 对象中存储的 IVsTextView 对象的 HighlightMatchingBrace 方法。 这将显示特定范围。

  11. LanguagePreferences 属性 EnableShowMatchingBrace 有效, HandleBracesResponse 方法获取匹配的范围包含的文本并显示该范围之前 80 个字符在状态栏中。 可以这样做时,如果 ParseSource 方法包括附带的相对的语言元素。 有关更多信息,请参见 EnableShowMatchingBrace 属性。

  12. 执行。

摘要

操作通常限于简单的匹配的大括号对语言元素。 更复杂的元素,如匹配的三个 ("if(…)”, “{”和 “}”或 “else”, “{”和 “}") 作为 Word 完成操作的一部分,因此,中显示。 例如,那么,当 “other”运行完成时,匹配 “if”语句中显示。 如果有一系列 if/else if 语句,所有可能会显示使用结构和匹配的大括号相同。 Source 基类中支持此操作,如下所示:扫描仪必须返回标记触发器值 MatchBraces 以及是在光标位置之前的标记的触发器值 MemberSelect

有关更多信息,请参见 括号匹配 (托管包结构)

分析的着色

Colorizing 源代码非常简单,标识标记的类型并返回有关该类型的颜色信息。 Colorizer 类作为在编辑器和 scan 程序之间的中间提供有关每个标记的颜色信息。 Colorizer 类在 colorizing 使用 IScanner 对象帮助行并收集所有行的状态信息在源文件中。 在 MPF 语言服务类中,,因为它与扫描仪仅通信是通过 IScanner 接口, Colorizer 类不必重写。 通过重写在 LanguageService 类的 GetScanner 方法提供对象实现 IScanner 接口。

提供 IScanner 扫描仪源代码行通过 SetSource 方法。 调用 ScanTokenAndProvideInfoAboutIt 方法重复获取在行的下一个标记,直到行用完标记。 对着色, MPF 将所有源代码作为行顺序。 因此,扫描程序必须能够处理位于它的源视为行。 此外,所有行可以随时通过为扫描仪,并且,唯一的确保为扫描仪在要浏览的行之前接收的行状态变量。

Colorizer 类还用于标识标记触发器。 这些触发器调用 MPF 特定标记可以启动更复杂的操作,例如字完成或匹配的大括号。 由于标识此触发器必须快,并且必须在任何位置出现,扫描仪最适用于此任务。

有关更多信息,请参见 语法 Colorizing (托管包结构)

分析功能和大小的

分析功能和大小的比标识遇到了标记有的类型需要更多工作。 该分析器必须标识标记的类型,不仅,而且该标记使用的功能。 例如,标识符是名称,但是,在该语言,标识符可能是类、命名空间、方法或变量的名称,具体取决于上下文。 该标记的泛型类型可能是标识符,但是,该标识符可以根据为,并且还有其他含义,它被定义为。 此确定了该分析器具有有关分析语言的更广泛的知识。 这是 AuthoringSink 类产生的原因。 AuthoringSink 类收集标识符的信息,方法,与语言为 (例如大括号和括号),并且,语言成三次,例如, (类似于语言为,但有三个部分 “foreach()”{”和 “}")。 此外,可以重写 AuthoringSink 类支持代码确定,用于断点的早期验证,以确保调试器不必加载和 汽车 调试窗口时,自动显示局部变量和参数,当程序进行调试时以及需要则分析器标识合适的局部变量和参数以外调试器存在。

作为 ParseRequest 对象的一部分, AuthoringSink 对象传递给分析器,,并且新的 ParseRequest 对象会创建一个新 AuthoringSink 对象每次创建。 此外, ParseSource 方法必须返回 AuthoringScope 对象,用于处理各种 IntelliSense 操作。 AuthoringScope 对象基于分析的原因维护声明的列表和方法的列表,之一,填充。 必须实现 AuthoringScope 类。

请参见

概念

语言服务概述 (托管包结构)

语法 Colorizing (托管包结构)

括号匹配 (托管包结构)

其他资源

实现使用托管包结构的语言服务