我如何处理AST中的评论?

Jen*_*off 11 delphi haskell comments abstract-syntax-tree

我正在使用Parsec编写Delphi代码解析器,我目前的AST数据结构如下所示:

module Text.DelphiParser.Ast where

data TypeName = TypeName String [String] deriving (Show)
type UnitName = String
data ArgumentKind = Const | Var | Out | Normal deriving (Show)
data Argument = Argument ArgumentKind String TypeName deriving (Show)
data MethodFlag = Overload | Override | Reintroduce | Static | StdCall deriving (Show)
data ClassMember = 
      ConstField String TypeName
    | VarField String TypeName
    | Property String TypeName String (Maybe String)
    | ConstructorMethod String [Argument] [MethodFlag]
    | DestructorMethod String [Argument] [MethodFlag]
    | ProcMethod String [Argument] [MethodFlag]
    | FunMethod String [Argument] TypeName [MethodFlag]
    | ClassProcMethod String [Argument] [MethodFlag]
    | ClassFunMethod String [Argument] TypeName [MethodFlag]
     deriving (Show)
data Visibility = Private | Protected | Public | Published deriving (Show)
data ClassSection = ClassSection Visibility [ClassMember] deriving (Show)
data Class = Class String [ClassSection] deriving (Show)
data Type = ClassType Class deriving (Show)
data Interface = Interface [UnitName] [Type] deriving (Show)
data Implementation = Implementation [UnitName]  deriving (Show)
data Unit = Unit String Interface Implementation deriving (Show)
Run Code Online (Sandbox Code Playgroud)

我想保留我的AST数据结构中的注释,我现在正试图弄清楚如何做到这一点.

我的解析器分为lexer和解析器(都用Parsec编写),我已经实现了注释令牌的lexing.

unit SomeUnit;

interface

uses
  OtherUnit1, OtherUnit2;

type
  // This is my class that does blabla
  TMyClass = class
  var
    FMyAttribute: Integer;
  public
    procedure SomeProcedure;
    { The constructor takes an argument ... }
    constructor Create(const Arg1: Integer);
  end;

implementation

end.
Run Code Online (Sandbox Code Playgroud)

令牌流如下所示:

[..., Type, LineComment " This is my class that does blabla", Identifier "TMyClass", Equals, Class, ...]
Run Code Online (Sandbox Code Playgroud)

解析器将其转换为:

Class "TMyClass" ...
Run Code Online (Sandbox Code Playgroud)

Class数据类型没有任何附加评论和意见以来(尤其是块注释)可能出现的令牌流中的几乎任何地方,我会一个可选的注释添加到AST的所有数据类型?

我如何处理AST中的评论?

Tik*_*vis 11

处理AST上的注释数据的一种合理方法是通过一个额外的类型参数来创建,该参数可以包含您喜欢的任何元数据.除了能够有选择地包含或忽略注释之外,这还允许您在树中包含其他类型的信息.

首先,您将使用额外参数重写所有AST类型:

data TypeName a = TypeName a String [String]
{- ... -}
data ClassSection a = ClassSection a Visibility [ClassMember a]
{- ... -}
Run Code Online (Sandbox Code Playgroud)

deriving Functor它们添加到所有它们中也很有用,可以很容易地转换给定AST上的注释.

现在,带有注释的AST将具有类型Class Comment或类似的效果.您还可以将其重用于范围分析等其他信息,其中您将当前范围包含在AST的相关部分中.

如果你想同时使用多个注释,最简单的解决方案是使用记录,虽然这有点尴尬,因为(至少现在¹)我们不能轻易地在记录字段上编写代码多态.(即我们不能轻易地写出"任何带有comments :: Comment字段的记录"类型.)

您可以做的另一个巧妙的事情是使用PatternSynonyms(可从GHC 7.8获得)使用一套模式,就像您当前未注释的AST一样,让您重用现有的case语句.(为此,您还必须重命名带注释类型的构造函数,以使它们不重叠.)

pattern TypeName a as <- TypeName' _ a as
Run Code Online (Sandbox Code Playgroud)

脚注

¹希望第2部分重新启动的重载记录字段提案在实际添加到语言时将在这方面提供帮助.