-- compiler/main/HscMain.hs hscParse'関数
hscParse' mod_summary = do
    dflags <- getDynFlags
    let src_filename = ms_hspp_file mod_summary
       maybe_src_buf = ms_hspp_buf mod_summary

  liftIO $ showPass dflags "Parser"
  {-# SCC "Parser" #-} do
  buf <- case maybe_src_buf of
          Just b -> return b
          Nothing -> liftIO $ hGetStringBuffer src_filename

  let loc = mkRealSrcLoc (mkFastString src_filename) 1 1
  case unP parseModule (mkPState dflags buf loc) of
     PFailed span err ->
liftIO $ showPass dflags "Parser"




*** Parser:
詳細:
http://www.kotha.net/ghcguide_ja/7.0.4/
profiling.html#idp19148320
liftIO $ dumpIfSet_dyn dflags Opt_D_dump_parsed
                   "Parser" $ ppr rdr_module




==================== Parser =============
module Queue (
      Queue(..)
   ) where
import Prelude hiding ( head, tail )
class Queue q where {
hscParse' :: ModSummary -> Hsc HsParsedModule
hscParse' mod_summary = do
   dflags <- getDynFlags
--snip--
   case unP parseModule (mkPState dflags buf loc) of
      PFailed span err ->
         liftIO $ throwOneError (mkPlainErrMsg span err)

      POk pst rdr_module -> do
         logWarningsReportErrors (getMessages pst)
--snip--
         return HsParsedModule {
               hpm_module = rdr_module,
               hpm_src_files = srcs2
                  }
unP parseModule (mkPState dflags buf loc)




* unP: compiler/parser/Lexer.xで定義
* parseModule: compiler/parser/Parser.y.ppで定義
* mkPState: compiler/parser/Lexer.xで定義
http://www.haskell.org/alex/
http://www.haskell.org/happy/
-- Parser.y.pp
%monad { P } { >>= } { return }
%lexer { lexer } { L _ ITeof }
%name parseModule module
%name parseStmt maybe_stmt
%name parseIdentifier identifier
%name parseType ctype
%partial parseHeader header
%tokentype { (Located Token) }




http://www.haskell.org/happy/doc/html/sec-monads.html
module :: { Located (HsModule RdrName) }
    : maybedocheader 'module' modid maybemodwarning 
                  maybeexports 'where' body
         {% fileSrcSpan >>=  loc ->
           return (L loc (HsModule (Just $3) $5 (fst $7)
                          (snd $7) $4 $1) )}
    | body2
         {% fileSrcSpan >>=  loc ->
           return (L loc (HsModule Nothing Nothing
               (fst $1) (snd $1) Nothing Nothing
                        )) }
GHCソースコード読みのススメ

GHCソースコード読みのススメ

  • 7.
    -- compiler/main/HscMain.hs hscParse'関数 hscParse'mod_summary = do dflags <- getDynFlags let src_filename = ms_hspp_file mod_summary maybe_src_buf = ms_hspp_buf mod_summary liftIO $ showPass dflags "Parser" {-# SCC "Parser" #-} do buf <- case maybe_src_buf of Just b -> return b Nothing -> liftIO $ hGetStringBuffer src_filename let loc = mkRealSrcLoc (mkFastString src_filename) 1 1 case unP parseModule (mkPState dflags buf loc) of PFailed span err ->
  • 8.
    liftIO $ showPassdflags "Parser" *** Parser:
  • 9.
  • 10.
    liftIO $ dumpIfSet_dyndflags Opt_D_dump_parsed "Parser" $ ppr rdr_module ==================== Parser ============= module Queue ( Queue(..) ) where import Prelude hiding ( head, tail ) class Queue q where {
  • 11.
    hscParse' :: ModSummary-> Hsc HsParsedModule hscParse' mod_summary = do dflags <- getDynFlags --snip-- case unP parseModule (mkPState dflags buf loc) of PFailed span err -> liftIO $ throwOneError (mkPlainErrMsg span err) POk pst rdr_module -> do logWarningsReportErrors (getMessages pst) --snip-- return HsParsedModule { hpm_module = rdr_module, hpm_src_files = srcs2 }
  • 12.
    unP parseModule (mkPStatedflags buf loc) * unP: compiler/parser/Lexer.xで定義 * parseModule: compiler/parser/Parser.y.ppで定義 * mkPState: compiler/parser/Lexer.xで定義
  • 13.
  • 14.
    -- Parser.y.pp %monad {P } { >>= } { return } %lexer { lexer } { L _ ITeof } %name parseModule module %name parseStmt maybe_stmt %name parseIdentifier identifier %name parseType ctype %partial parseHeader header %tokentype { (Located Token) } http://www.haskell.org/happy/doc/html/sec-monads.html
  • 17.
    module :: {Located (HsModule RdrName) } : maybedocheader 'module' modid maybemodwarning maybeexports 'where' body {% fileSrcSpan >>= loc -> return (L loc (HsModule (Just $3) $5 (fst $7) (snd $7) $4 $1) )} | body2 {% fileSrcSpan >>= loc -> return (L loc (HsModule Nothing Nothing (fst $1) (snd $1) Nothing Nothing )) }