2015-05-04 8 views
10

Piszę kodu parser Delphi za pomocą parsec, moje obecne struktury danych AST wyglądać następująco:Jak radzić sobie z komentarzami w moim 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) 

chcę zachować komentarze w moich struktur danych AST i jestem obecnie próbuje dowiedzieć się, jak to zrobić to.

Mój parser jest podzielony na leksera i parser (oba napisane za pomocą Parsetu), a ja już zaimplementowałem leksykację komentarzy.

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. 

Token strumień wygląda następująco:

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

Parser przekłada się to na:

Class "TMyClass" ... 

Typ Class danych nie ma żadnego sposobu, aby dołączyć komentarze i od komentarzy (szczególnie komentarze blokowe) mogą pojawić się prawie wszędzie w strumieniu tokenów, musiałbym dodać opcjonalny komentarz do wszystkich typów danych w AST?

Jak radzić sobie z komentarzami w moim AST?

+0

patrz również http://stackoverflow.com/questions/9392546/pretty-print-haskell-source-code- z-komentarzami i sprawdź, jak są zdefiniowane te AST. Np. Http://hackage.haskell.org/package/haskell-src-exts-1.16.0.1/docs/Language-Haskell-Exts-Annotated-Syntax.html jest polimorficzna w adnotacji. – d8d0d65b3f7cf42

Odpowiedz

11

Rozsądnym podejściem do przetwarzania danych z adnotacjami na AST jest zawiązywanie w nim parametru dodatkowego typu, który może zawierać dowolne dowolne metadane. Oprócz możliwości selektywnego dołączania lub ignorowania komentarzy, pozwala to również na dołączanie innych informacji do drzewa.

pierwsze, należy przepisać wszystkie rodzaje AST z dodatkowym parametrem:

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

Dobrze byłoby, aby dodać deriving Functor do wszystkich z nich, a także, dzięki czemu można łatwo przekształcić adnotacje na danym AST .

Teraz AST z pozostałymi komentarzami będzie miał typ Class Comment lub coś podobnego. Można również użyć go ponownie w celu uzyskania dodatkowych informacji, takich jak analiza zakresu, w których można zawrzeć obecny zakres z odpowiednią częścią AST.

Jeśli chciałeś wielu adnotacji naraz, najprostszym rozwiązaniem byłoby użycie rekordu, chociaż jest to trochę niezręczne, ponieważ (przynajmniej na razie¹) nie możemy łatwo napisać kodu polimorficznego nad polami zapisu. (Tj. Nie możemy łatwo napisać typu "dowolny rekord z polem comments :: Comment").

Jedną dodatkową rzeczą, którą możesz zrobić, to użyć PatternSynonyms (dostępnej z GHC 7.8), aby mieć zestaw wzorców, które działają tak jak Twój obecny niezarejestrowany AST, umożliwiając ponowne wykorzystanie istniejących stwierdzeń dotyczących spraw. (Aby to zrobić, będziesz też musiał zmienić nazwę konstruktorów dla adnotacjami rodzaju, żeby nie zachodziły na siebie.)

pattern TypeName a as <- TypeName' _ a as 

Przypisy

¹ Mam nadzieję, że część 2 revived overloaded record fields proposal pomogą w tym uważać, kiedy faktycznie zostanie dodany do języka.

Powiązane problemy