    -----------------------------------------------------------------------------
    Generating info files.

    (c) 1993-2001 Andy Gill, Simon Marlow
    -----------------------------------------------------------------------------

    > module Happy.Tabular.Info (genInfoFile) where

    > import Data.Set ( Set )
    > import qualified Data.Set as Set hiding ( Set )
    > import Happy.Grammar
    > import Happy.Grammar.ExpressionWithHole ( substExpressionWithHole )
    > import Happy.Tabular.LALR   ( Lr0Item(..), LRAction(..), Goto(..), GotoTable, ActionTable )

    > import Data.Array
    > import Data.List (nub)
    > import Data.Version           ( Version, showVersion )

    Produce a file of parser information, useful for debugging the parser.

    > genInfoFile
    >       :: [Set Lr0Item]
    >       -> Grammar e
    >       -> ActionTable
    >       -> GotoTable
    >       -> Array Int (Int,Int)
    >       -> String
    >       -> [Int]                        -- unused rules
    >       -> [String]                     -- unused terminals
    >       -> Version
    >       -> String

    > genInfoFile :: forall e.
    [Set Lr0Item]
    -> Grammar e
    -> ActionTable
    -> GotoTable
    -> Array Int (Int, Int)
    -> String
    -> [Int]
    -> [String]
    -> Version
    -> String
    genInfoFile [Set Lr0Item]
    items
    >       (Grammar { productions :: forall eliminator. Grammar eliminator -> [Production eliminator]
    productions = [Production e]
    prods
    >                , lookupProdNo :: forall eliminator.
    Grammar eliminator -> Int -> Production eliminator
    lookupProdNo = Int -> Production e
    lookupProd
    >                , lookupProdsOfName :: forall eliminator. Grammar eliminator -> Name -> [Int]
    lookupProdsOfName = Name -> [Int]
    lookupProdNos
    >                , non_terminals :: forall eliminator. Grammar eliminator -> [Name]
    non_terminals = [Name]
    nonterms
    >                , token_names :: forall eliminator. Grammar eliminator -> Array Name String
    token_names = Array Name String
    env
    >                , token_specs :: forall eliminator. Grammar eliminator -> [(Name, TokenSpec)]
    token_specs = [(Name, TokenSpec)]
    tokens
    >                })
    >        ActionTable
    action GotoTable
    goto Array Int (Int, Int)
    conflictArray String
    filename [Int]
    unused_rules [String]
    unused_terminals Version
    version
    >       = (String -> String
    showHeader
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    showConflicts
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    showUnused
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    showProductions
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    showTerminals
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    showNonTerminals
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    showStates
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    showStats
    >       ) String
    ""
    >   where

    >   showHeader :: String -> String
    showHeader
    >       = String -> String -> String
    banner (String
    "Info file generated by Happy Version " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
    >                 Version -> String
    showVersion Version
    version String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    " from " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    filename)

    >   showConflicts :: String -> String
    showConflicts
    >       = String -> String -> String
    str String
    "\n"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((String -> String) -> (String -> String) -> String -> String)
    -> (String -> String) -> [String -> String] -> String -> String
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.) String -> String
    forall a. a -> a
    id (((Int, (Int, Int)) -> String -> String)
    -> [(Int, (Int, Int))] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int, (Int, Int)) -> String -> String
    forall {a} {a} {a}.
    (Eq a, Eq a, Num a, Num a, Show a, Show a, Show a) =>
    (a, (a, a)) -> String -> String
    showConflictsState (Array Int (Int, Int) -> [(Int, (Int, Int))]
    forall i e. Ix i => Array i e -> [(i, e)]
    assocs Array Int (Int, Int)
    conflictArray))
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"

    >   showConflictsState :: (a, (a, a)) -> String -> String
    showConflictsState (a
    _,     (a
    0,a
    0)) = String -> String
    forall a. a -> a
    id
    >   showConflictsState (a
    state, (a
    sr,a
    rr))
    >       = String -> String -> String
    str String
    "state "
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> String -> String
    forall a. Show a => a -> String -> String
    shows a
    state
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    " contains "
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave' String
    " and " (
    >               (if a
    sr a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    /= a
    0
    >                       then [ a -> String -> String
    forall a. Show a => a -> String -> String
    shows a
    sr (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    " shift/reduce conflicts" ]
    >                       else []) [String -> String] -> [String -> String] -> [String -> String]
    forall a. [a] -> [a] -> [a]
    ++
    >                if a
    rr a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    /= a
    0
    >                       then [ a -> String -> String
    forall a. Show a => a -> String -> String
    shows a
    rr (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    " reduce/reduce conflicts" ]
    >                       else [])
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    ".\n"

    >   showUnused :: String -> String
    showUnused =
    >         (case [Int]
    unused_rules of
    >           [] -> String -> String
    forall a. a -> a
    id
    >           [Int]
    _  ->   String -> [String -> String] -> String -> String
    interleave String
    "\n" (
    >                       (Int -> String -> String) -> [Int] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Int
    r ->   String -> String -> String
    str String
    "rule "
    >                                  (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows Int
    r
    >                                  (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    " is unused")
    >                               [Int]
    unused_rules)
    >                 (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n")
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (case [String]
    unused_terminals of
    >           [] -> String -> String
    forall a. a -> a
    id
    >           [String]
    _  ->   String -> [String -> String] -> String -> String
    interleave String
    "\n" (
    >                       (String -> String -> String) -> [String] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map (\String
    t ->   String -> String -> String
    str String
    "terminal "
    >                                  (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    t
    >                                  (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    " is unused")
    >                               [String]
    unused_terminals)
    >                 (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n")

    >   showProductions :: String -> String
    showProductions =
    >         String -> String -> String
    banner String
    "Grammar"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave String
    "\n" ((Production e -> Int -> String -> String)
    -> [Production e] -> [Int] -> [String -> String]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith Production e -> Int -> String -> String
    forall {a} {eliminator}.
    Show a =>
    Production eliminator -> a -> String -> String
    showProduction [Production e]
    prods [ Int
    0 :: Int .. ])
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"

    >   showProduction :: Production eliminator -> a -> String -> String
    showProduction (Production Name
    nt [Name]
    toks (eliminator, [Int])
    _sem Priority
    _prec) a
    i
    >       = Int -> (String -> String) -> String -> String
    ljuststr Int
    50 (
    >         String -> String -> String
    str String
    "\t"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> String -> String
    showName Name
    nt
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    " -> "
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave String
    " " ((Name -> String -> String) -> [Name] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map Name -> String -> String
    showName [Name]
    toks))
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "  (" (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> String -> String
    forall a. Show a => a -> String -> String
    shows a
    i (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    ")"

    >   showStates :: String -> String
    showStates =
    >         String -> String -> String
    banner String
    "States"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave String
    "\n" (([Lr0Item] -> Int -> String -> String)
    -> [[Lr0Item]] -> [Int] -> [String -> String]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith [Lr0Item] -> Int -> String -> String
    showState
    >               ((Set Lr0Item -> [Lr0Item]) -> [Set Lr0Item] -> [[Lr0Item]]
    forall a b. (a -> b) -> [a] -> [b]
    map Set Lr0Item -> [Lr0Item]
    forall a. Set a -> [a]
    Set.toAscList [Set Lr0Item]
    items) [ Int
    0 :: Int .. ])

    >   showState :: [Lr0Item] -> Int -> String -> String
    showState [Lr0Item]
    state Int
    n
    >       = String -> String -> String
    str String
    "State "(String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows Int
    n
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n\n"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave String
    "\n" ((Lr0Item -> String -> String) -> [Lr0Item] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map Lr0Item -> String -> String
    showItem [Lr0Item]
    selectedItems)
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((String -> String) -> (String -> String) -> String -> String)
    -> (String -> String) -> [String -> String] -> String -> String
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.) String -> String
    forall a. a -> a
    id (((Name, LRAction) -> String -> String)
    -> [(Name, LRAction)] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map (Name, LRAction) -> String -> String
    showAction (Array Name LRAction -> [(Name, LRAction)]
    forall i e. Ix i => Array i e -> [(i, e)]
    assocs (ActionTable
    action ActionTable -> Int -> Array Name LRAction
    forall i e. Ix i => Array i e -> i -> e
    ! Int
    n)))
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((String -> String) -> (String -> String) -> String -> String)
    -> (String -> String) -> [String -> String] -> String -> String
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.) String -> String
    forall a. a -> a
    id (((Name, Goto) -> String -> String)
    -> [(Name, Goto)] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map (Name, Goto) -> String -> String
    showGoto (Array Name Goto -> [(Name, Goto)]
    forall i e. Ix i => Array i e -> [(i, e)]
    assocs (GotoTable
    goto GotoTable -> Int -> Array Name Goto
    forall i e. Ix i => Array i e -> i -> e
    ! Int
    n)))
    >     where
    >       nonRuleItems :: [Lr0Item]
    nonRuleItems  = [ (Int -> Int -> Lr0Item
    Lr0 Int
    r Int
    d) | (Lr0 Int
    r Int
    d) <- [Lr0Item]
    state, Int
    d Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    0 ]
    >       selectedItems :: [Lr0Item]
    selectedItems = if [Lr0Item] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Lr0Item]
    nonRuleItems then Int -> [Lr0Item] -> [Lr0Item]
    forall a. Int -> [a] -> [a]
    take Int
    1 [Lr0Item]
    state else [Lr0Item]
    nonRuleItems
    >         -- andreasabel, 2019-11-12, issue #161:
    >         -- Items that start with a dot (@d == 0@) are usually added by completion
    >         -- and thus redundant and dropped from the printout (@nonRuleItems@).
    >         -- However, if the initial item started with a dot, it should not be dropped,
    >         -- otherwise there will be no items left.  Thus, should there be no items
    >         -- not starting with a dot, we print the initial item.

    >   showItem :: Lr0Item -> String -> String
    showItem (Lr0 Int
    rule Int
    dot)
    >       = Int -> (String -> String) -> String -> String
    ljuststr Int
    50 (
    >                 String -> String -> String
    str String
    "\t"
    >               (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> String -> String
    showName Name
    nt
    >               (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    " -> "
    >               (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave String
    " " ((Name -> String -> String) -> [Name] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map Name -> String -> String
    showName [Name]
    beforeDot)
    >               (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    ". "
    >               (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave String
    " " ((Name -> String -> String) -> [Name] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map Name -> String -> String
    showName [Name]
    afterDot))
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "   (rule " (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows Int
    rule (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    ")"
    >       where
    >               Production Name
    nt [Name]
    toks (e, [Int])
    _sem Priority
    _prec = Int -> Production e
    lookupProd Int
    rule
    >               ([Name]
    beforeDot, [Name]
    afterDot) = Int -> [Name] -> ([Name], [Name])
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    dot [Name]
    toks

    >   showAction :: (Name, LRAction) -> String -> String
    showAction (Name
    _, LRAction
    LR'Fail)
    >       = String -> String
    forall a. a -> a
    id
    >   showAction (Name
    t, LRAction
    act)
    >       = String -> String -> String
    str String
    "\t"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Name -> String -> String
    showJName Int
    15 Name
    t
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LRAction -> String -> String
    showAction' LRAction
    act
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"

    >   showAction' :: LRAction -> String -> String
    showAction' LRAction
    LR'MustFail
    >       = String -> String -> String
    str String
    "fail"
    >   showAction' (LR'Shift Int
    n Priority
    _)
    >       = String -> String -> String
    str String
    "shift, and enter state "
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows Int
    n
    >   showAction' LRAction
    LR'Accept
    >       = String -> String -> String
    str String
    "accept"
    >   showAction' (LR'Reduce Int
    n Priority
    _)
    >       = String -> String -> String
    str String
    "reduce using rule "
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows Int
    n
    >   showAction' (LR'Multiple [LRAction]
    as LRAction
    a)
    >       = LRAction -> String -> String
    showAction' LRAction
    a
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave String
    "\n"
    >               ((LRAction -> String -> String) -> [LRAction] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map (\LRAction
    a' -> String -> String -> String
    str String
    "\t\t\t(" (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LRAction -> String -> String
    showAction' LRAction
    a' (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    ")")
    >                ([LRAction] -> [LRAction]
    forall a. Eq a => [a] -> [a]
    nub ((LRAction -> Bool) -> [LRAction] -> [LRAction]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (LRAction -> LRAction -> Bool
    forall a. Eq a => a -> a -> Bool
    /= LRAction
    a) [LRAction]
    as)))
    >   showAction' LRAction
    LR'Fail = String -> String -> String
    forall a. HasCallStack => String -> a
    error String
    "showAction' LR'Fail: Unhandled case"

    >   showGoto :: (Name, Goto) -> String -> String
    showGoto (Name
    _, Goto
    NoGoto)
    >       = String -> String
    forall a. a -> a
    id
    >   showGoto (Name
    nt, Goto Int
    n)
    >       = String -> String -> String
    str String
    "\t"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Name -> String -> String
    showJName Int
    15 Name
    nt
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "goto state "
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows Int
    n
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"

    >   showTerminals :: String -> String
    showTerminals
    >       = String -> String -> String
    banner String
    "Terminals"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave String
    "\n" (((Name, TokenSpec) -> String -> String)
    -> [(Name, TokenSpec)] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map (Name, TokenSpec) -> String -> String
    showTerminal [(Name, TokenSpec)]
    tokens)
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"

    >   showTerminal :: (Name, TokenSpec) -> String -> String
    showTerminal (Name
    t,TokenSpec
    s)
    >       = String -> String -> String
    str String
    "\t"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Name -> String -> String
    showJName Int
    15 Name
    t
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "{ " (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TokenSpec -> String -> String
    showToken TokenSpec
    s (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    " }"

    >   showToken :: TokenSpec -> String -> String
    showToken (TokenFixed String
    s) = String -> String -> String
    str String
    s
    >   showToken (TokenWithValue ExpressionWithHole
    e) = String -> String -> String
    str (String -> String -> String) -> String -> String -> String
    forall a b. (a -> b) -> a -> b
    $ ExpressionWithHole -> String -> String
    substExpressionWithHole ExpressionWithHole
    e String
    "$$"

    >   showNonTerminals :: String -> String
    showNonTerminals
    >       = String -> String -> String
    banner String
    "Non-terminals"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String -> String] -> String -> String
    interleave String
    "\n" ((Name -> String -> String) -> [Name] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map Name -> String -> String
    showNonTerminal [Name]
    nonterms)
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"

    >   showNonTerminal :: Name -> String -> String
    showNonTerminal Name
    nt
    >       = String -> String -> String
    str String
    "\t"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Name -> String -> String
    showJName Int
    15 Name
    nt
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (if ([String -> String] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [String -> String]
    nt_rules Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    1)
    >               then String -> String -> String
    str String
    " rule  "
    >               else String -> String -> String
    str String
    " rules ")
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((String -> String) -> (String -> String) -> String -> String)
    -> [String -> String] -> String -> String
    forall a. (a -> a -> a) -> [a] -> a
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    foldr1 (\String -> String
    a String -> String
    b -> String -> String
    a (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    ", " (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    b) [String -> String]
    nt_rules
    >       where nt_rules :: [String -> String]
    nt_rules = (Int -> String -> String) -> [Int] -> [String -> String]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> String -> String
    forall a. Show a => a -> String -> String
    shows (Name -> [Int]
    lookupProdNos Name
    nt)

    >   showStats :: String -> String
    showStats
    >       = String -> String -> String
    banner String
    "Grammar Totals"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str   String
    "Number of rules: " (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows ([Production e] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Production e]
    prods)
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\nNumber of terminals: " (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows ([(Name, TokenSpec)] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [(Name, TokenSpec)]
    tokens)
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\nNumber of non-terminals: " (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows ([Name] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Name]
    nonterms)
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\nNumber of states: " (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    forall a. Show a => a -> String -> String
    shows ([Set Lr0Item] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Set Lr0Item]
    items)
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n"

    >   nameOf :: Name -> String
    nameOf Name
    n    = Array Name String
    env Array Name String -> Name -> String
    forall i e. Ix i => Array i e -> i -> e
    ! Name
    n
    >   showName :: Name -> String -> String
    showName    = String -> String -> String
    str (String -> String -> String)
    -> (Name -> String) -> Name -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> String
    nameOf
    >   showJName :: Int -> Name -> String -> String
    showJName Int
    j = String -> String -> String
    str (String -> String -> String)
    -> (Name -> String) -> Name -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> String
    ljustify Int
    j (String -> String) -> (Name -> String) -> Name -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> String
    nameOf

    > ljustify :: Int -> String -> String
    > ljustify :: Int -> String -> String
    ljustify Int
    n String
    s = String
    s String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> Char -> String
    forall a. Int -> a -> [a]
    replicate (Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max Int
    0 (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - String -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length String
    s)) Char
    ' '

    > ljuststr :: Int -> (String -> String) -> String -> String
    > ljuststr :: Int -> (String -> String) -> String -> String
    ljuststr Int
    n String -> String
    s = String -> String -> String
    str (Int -> String -> String
    ljustify Int
    n (String -> String
    s String
    ""))

    > banner :: String -> String -> String
    > banner :: String -> String -> String
    banner String
    s
    >       = String -> String -> String
    str String
    "-----------------------------------------------------------------------------\n"
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    s
    >       (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    "\n-----------------------------------------------------------------------------\n"

    > str :: String -> String -> String
    > str :: String -> String -> String
    str = String -> String -> String
    showString
    > interleave :: String -> [String -> String] -> String -> String
    > interleave :: String -> [String -> String] -> String -> String
    interleave String
    s = ((String -> String) -> (String -> String) -> String -> String)
    -> (String -> String) -> [String -> String] -> String -> String
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\String -> String
    a String -> String
    b -> String -> String
    a (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    s (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    b) String -> String
    forall a. a -> a
    id
    > interleave' :: String -> [String -> String] -> String -> String
    > interleave' :: String -> [String -> String] -> String -> String
    interleave' String
    s = ((String -> String) -> (String -> String) -> String -> String)
    -> [String -> String] -> String -> String
    forall a. (a -> a -> a) -> [a] -> a
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    foldr1 (\String -> String
    a String -> String
    b -> String -> String
    a (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String -> String
    str String
    s (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    b)