[英]How can I deal with comments in my AST?
我正在使用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數據結構中的注釋,我現在正試圖弄清楚如何做到這一點。
我的解析器分為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.
令牌流如下所示:
[..., Type, LineComment " This is my class that does blabla", Identifier "TMyClass", Equals, Class, ...]
解析器將其轉換為:
Class "TMyClass" ...
Class
數據類型沒有任何附加注釋的方法,因為注釋(尤其是塊注釋)幾乎可以出現在令牌流中的任何位置,我必須向AST中的所有數據類型添加可選注釋嗎?
我如何處理AST中的評論?
處理AST上的注釋數據的一種合理方法是通過一個額外的類型參數來創建,該參數可以包含您喜歡的任何元數據。 除了能夠有選擇地包含或忽略注釋之外,這還允許您在樹中包含其他類型的信息。
首先,您將使用額外參數重寫所有AST類型:
data TypeName a = TypeName a String [String]
{- ... -}
data ClassSection a = ClassSection a Visibility [ClassMember a]
{- ... -}
將deriving Functor
添加到所有這些中也很有用,可以輕松轉換給定AST上的注釋。
現在,帶有注釋的AST將具有Class Comment
類型或類似的效果。 您還可以將其重用於范圍分析等其他信息,其中您將當前范圍包含在AST的相關部分中。
如果你想同時使用多個注釋,最簡單的解決方案是使用記錄,雖然這有點尷尬,因為(至少現在¹)我們不能輕易地在記錄字段上編寫代碼多態。 (即我們不能輕易地寫出“帶comments :: Comment
任何記錄comments :: Comment
字段”。)
您可以做的另一個巧妙的事情是使用PatternSynonyms
(可從GHC 7.8獲得)來獲得一套模式,這些模式就像您當前未注釋的AST一樣,讓您重用現有的case語句。 (為此,您還必須重命名帶注釋類型的構造函數,以使它們不重疊。)
pattern TypeName a as <- TypeName' _ a as
腳注
¹希望第2部分重新啟動的重載記錄字段提案在實際添加到語言時將在這方面提供幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.