Я работаю над проектом для анализа кода Haskell. Я решил использовать GHC, чтобы проанализировать источник и вывести типы, а не написать мой собственный код, чтобы сделать это. Прямо сейчас я являюсь упорным через документы Пикши, но это - медленное движение. Кто-либо знает о хорошем учебном руководстве?
Править: Для разъяснения я не ищу что-то как hlint. Я пишу свой собственный инструмент для анализа характеристик во время выполнения кода Haskell, таким образом, он похож, я пишу другой hlint. То, что я ищу, является в основном расширением страницы GHC As Wiki библиотека.
Адам, это довольно сложная задача. С момента своего появления в 2006 году API GHC был несколько недокументирован. Я бы посоветовал попытаться найти несколько небольших приложений, которые были написаны с использованием GHC API. Правильным местом для этого, вероятно, является список рассылки пользователей GHC.
Одной из таких программ является ghctags
, которая поставляется вместе с деревом исходников GHC. Я написал первоначальную версию, но не могу ее рекомендовать - в коде так много следов, что я больше не могу за ним следить. Лучшее, что я могу сказать, это то, что хотя за ней трудно уследить, она, по крайней мере, маленькая и трудная - гораздо проще, чем весь GHC.
В Haskell wiki и GHC documentation, вероятно, есть то, что вы ищете, если поискать статьи. Также вас может заинтересовать инструмент hlint для проверки синтаксиса и других вещей в вашем исходном коде.
Ах! Нашел гораздо лучшую точку входа в документацию на: http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-6.12.1/GHC.html
Я обновил wikipage этим примером:
Здесь мы демонстрируем вызов parseModule, typecheckModule, desugarModule, getNamesInScope и getModuleGraph. Это работает для haskell-платформы, ghc-6.12.1.
ошибки: libdir жестко закодирован. См. ghc-paths выше.
--A.hs
--invoke: ghci -package ghc A.hs
import GHC
import Outputable
--import GHC.Paths ( libdir )
import DynFlags ( defaultDynFlags )
libdir = "/usr/local/lib/ghc-6.12.1"
targetFile = "B.hs"
main = do
res <- example
print $ showSDoc ( ppr res )
example =
defaultErrorHandler defaultDynFlags $ do
runGhc (Just libdir) $ do
dflags <- getSessionDynFlags
setSessionDynFlags dflags
target <- guessTarget targetFile Nothing
setTargets [target]
load LoadAllTargets
modSum <- getModSummary $ mkModuleName "B"
p <- parseModule modSum
t <- typecheckModule p
d <- desugarModule t
l <- loadModule d
n <- getNamesInScope
c <- return $ coreModule d
g <- getModuleGraph
mapM showModule g
return $ (parsedSource d,"/n-----/n", typecheckedSource d)
--B.hs
module B where
main = print "Hello, World!"
Если парсинг - это самое главное, я рекомендую haskell-src-exts. Он разбирает весь Haskell98, целую кучу расширений и очень прост в использовании.