Jak każdy już powiedział haskell-src-meta
zapewnia
parsePat :: String -> Either String Pat
parseExp :: String -> Either String Exp
parseType :: String -> Either String Type
parseDecs :: String -> Either String [Dec]
gdzie Pat
, Exp
, Type
i Dec
są takie same jak z Language.Haskell.TH.Syntax
.
Dlaczego nie GHC narażać własnego parsera?
To robi. Uruchomienie GHCi z ghci -package ghc
(ghc
jest domyślnie ukrytym pakietem) i możesz zaimportować Parser
. Ma funkcje do analizy String
na wstępne AST (których deklaracje danych są w HsSyn
) dla wzorów, wyrażeń, typów i deklaracji.
OK, to dlaczego nie istnieją biblioteki, który używa tego parsera i przekształca swoje wyjście być AST od template-haskell
(jednego w Language.Haskell.TH.Syntax
)?
Patrząc wewnątrz HsSyn
, jego oczywiste, że AST nie jest zupełnie taka sama jak w Language.Haskell.TH.Syntax
. Otwórz oba: HsExpr
i Exp
, a obok siebie zobaczysz, że ten ostatni jest wypełniony typami takimi jak PostTc id <some-other-type>
i PostRn id <some-other-type>
. Kiedy AST jest przekazywana z parsera do renamera do sprawdzania typu, te bity i części powoli się wypełniają.Na przykład, nie znamy nawet fiksacji operatorów, dopóki nie przejdziemy do sprawdzania typów!
Aby uzyskać pożądane funkcje, musielibyśmy uruchomić o wiele więcej niż tylko analizator składni (przynajmniej rewizor i sprawdzanie typu również, być może więcej). Wyobraź sobie, że: za każdym razem, gdy chcesz przeanalizować nawet małe wyrażenie, takie jak "1 + 2"
, musisz jeszcze sprawdzić typ importu. Nawet wtedy, konwersja z powrotem do Language.Haskell.TH.Syntax
nie byłaby spacerkiem w parku: GHC ma wiele osobliwości, takich jak własny specjalny globalny sposób przechowywania nazw i identyfikatorów.
Hmmm ... ale co robi GHC z quasi-cytatami?
To jest fajna część! W przeciwieństwie do Exp
, HsExpr
ma HsSplice
do reprezentowania splotów. Spójrz na typy, dla pierwszych dwóch konstruktorów:
HsTypedSplice :: id -> LHsExpr id -> HsSplice id. -- things like [|| 1 + 2 ||]
HsUntypedSplice :: id -> LHsExpr id -> HsSplice id -- things like [| 1 + 2 |]
Zauważ, że nie są one przechowywanie String
, są już przechowywania AST! Splices są analizowane w tym samym czasie co reszta AST. I podobnie jak w pozostałej części AST spawy będą przejdzie wraz z renamer, typ sprawdzania itp gdzie brakujące dane zostaną wypełnione.
Więc jest to całkowicie niemożliwe, aby użyć parsera GHC za
Prawdopodobnie nie. Ale wyrzucenie go z reszty GHC może być dość trudne. Jeśli chcesz użyć parsera GHC, musimy również uruchomić sprawdzanie typu i zmianę nazwy, może być bardziej elegancko i prostiej po prostu użyć niezależnego analizatora składni, takiego jak haskell-src-exts
(czyli od tego zależy Haskell-src-meta
), który jest w stanie zrobić wszystko w jednym przebiegu (Fixions, na przykład, są jedną z rzeczy, które musisz dać przed czasem do tego parsera).
Wierzę, że [haskell-src-meta] (https://hackage.haskell.org/package/haskell-src-meta) zapewnia to – luqui
@luqui Jestem nieco zdezorientowany tym pakietem. W opisie jest napisane, że coś jest "jeszcze nie w 100%". Czy ta funkcja nie powinna już istnieć w GHC? Musi tak być, ponieważ zajmuje '[| | 1+) |] i jest całkowicie zdolny do przekształcenia go w' (InfixE _) '. Dlaczego więc istnieje zapotrzebowanie na pakiet stron trzecich, który może, ale nie musi, być przetwarzany poprawnie? Czy też błędnie interpretuję i to jest kod kanoniczny, którego używa GHC? Czy GHC po prostu nie ujawnia tej funkcji? Byłbym wdzięczny za jasność w tej sprawie. :) – Wizek
AFAIU GHC nie ujawnia tego kodu, ale nie jestem ekspertem TH – luqui