8.6. Basic monadic Happy use with Alex
Prev | Chapter 8. Tips | Next

## 8.6. Basic monadic Happy use with Alex

Alex lexers are often used by Happy parsers, for example in GHC. While many of these applications are quite sophisticated, it is still quite useful to combine the basic Happy `%monad` directive with the Alex `monad` wrapper. By using monads for both, the resulting parser and lexer can handle errors far more gracefully than by throwing an exception.

The most straightforward way to use a monadic Alex lexer is to simply use the `Alex` monad as the Happy monad:

Example 8.1. Lexer.x

    {
    module Lexer where
    }

    %wrapper "monad"

    tokens :-
      ...

    {
    data Token = ... | EOF
      deriving (Eq, Show)

    alexEOF = return EOF
    }

Example 8.2. Parser.y

    {
    module Parser where

    import Lexer
    }

    %name pFoo
    %tokentype { Token }
    %error { parseError }
    %monad { Alex } { >>= } { return }
    %lexer { lexer } { EOF }

    %token
      ...

    %%
      ...

    parseError :: Token -> Alex a
    parseError _ = do
      ((AlexPn _ line column), _, _, _) <- alexGetInput
      alexError ("parse error at line " ++ (show line) ++ ", column " ++ (show column))

    lexer :: (Token -> Alex a) -> Alex a
    lexer = (alexMonadScan >>=)
    }

We can then run the finished parser in the `Alex` monad using `runAlex`, which returns an `Either` value rather than throwing an exception in case of a parse or lexical error:

    import qualified Lexer as Lexer
    import qualified Parser as Parser

    parseFoo :: String -> Either String Foo
    parseFoo s = Lexer.runAlex s Parser.pFoo

Prev | Up | Next
8.5. Using Happy with GHCi | Home | Index