이렇게 하면 될 것 같다:

type Terminal = Maybe String

type Nonterminal = String

type Precedence = Int

type Production = (Nonterminal, [Symbol])

type ParserS = Int

data Associativity
___ = NONE
___ | LEFT
___ | RIGHT
___ deriving (Eq, Ord)

data Symbol
___ = Nonterminal Nonterminal
___ | Terminal Terminal
___ deriving (Eq, Ord)

data CFGrammar = CFGrammar {
___ getStartSym :: Nonterminal,
___ getTerminalSyms :: Map.Map Terminal (Precedence, Associativity)
___ getProductionRules :: Map.Map Production Precedence
} deriving ()

data LR1Parser = LR1Parser {
___ getInitialS :: ParserS,
___ getNextTable :: Map.Map (ParserS, Symbol) ParserS,
___ getReduceTable :: Map.Map (ParserS, Terminal) Production
} deriving ()

data PTree token
___ = Leaf token
___ | Branch Nonterminal [PTree token]
___ deriving (Eq, Ord)

class IsToken token where
___ getToken :: String → (token, String)
___ toTerminalSym :: token → Terminal

getCFG :: FilePath → ExceptT String IO CFG

getLALR1 :: CFG → ExceptT String Identity LR1Parser

getPTree :: IsToken token => LR1Parser → ExceptT String Identity (PTree token)

- dc official App