【问题标题】:How can I deal with comments in my AST?如何处理 AST 中的评论?
【发布时间】:2015-05-04 15:27:14
【问题描述】:

我正在使用 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)

我想在我的 AST 数据结构中保留 cmets,我目前正试图弄清楚如何做到这一点。

我的解析器分为一个词法分析器和一个解析器(都用 Parsec 编写),我已经实现了注释标记的词法分析。

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.

令牌流如下所示:

[..., Type, LineComment " This is my class that does blabla", Identifier "TMyClass", Equals, Class, ...]

解析器将其翻译成:

Class "TMyClass" ...

Class 数据类型没有任何附加 cmets 的方法,并且由于 cmets(尤其是块 cmets)几乎可以出现在令牌流中的任何位置,我是否必须为 AST 中的所有数据类型添加可选注释?

如何处理我的 AST 中的 cmets?

【问题讨论】:

标签: delphi haskell comments abstract-syntax-tree


【解决方案1】:

在 AST 上处理带注释的数据的合理方法是通过线程处理一个额外的类型参数,该参数可以包含您喜欢的任何元数据。除了能够选择性地包含或忽略 cmets 之外,这还可以让您在树中包含其他类型的信息。

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

data TypeName a = TypeName a String [String]
{- ... -}
data ClassSection a = ClassSection a Visibility [ClassMember a]
{- ... -}

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

现在剩余 cmets 的 AST 将具有 Class Comment 类型或类似的东西。您还可以将其重用于范围分析等附加信息,您可以将当前范围包含在 AST 的相关部分中。

如果您想要一次多个注释,最简单的解决方案是使用记录,尽管这有点尴尬,因为(至少现在¹)我们不能轻松地在记录字段上编写多态代码。 (即我们不能轻易写出类型“任何带有comments :: Comment 字段的记录”。)

您可以做的另一件事是使用PatternSynonyms(可从 GHC 7.8 获得)拥有一套与您当前未注释的 AST 一样工作的模式,让您可以重用现有的案例语句。 (为此,您还必须重命名带注释类型的构造函数,以免它们重叠。)

pattern TypeName a as <- TypeName' _ a as

脚注

¹ 希望第 2 部分 revived overloaded record fields proposal 在实际添加到语言中时能在这方面有所帮助。

【讨论】:

    猜你喜欢
    • 2012-01-03
    • 2020-06-30
    • 1970-01-01
    • 2020-07-30
    • 2012-10-04
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    相关资源
    最近更新 更多