The %token, %typeclass,
and %action directives can be used to cause
Alex to emit additional type signatures in generated
code. This allows the use of typeclasses in generated lexers.
The %token directive can be used to
specify the token type when any kind of
%wrapper directive has been given.
Whenever %token is used, the
%typeclass directive can also be used to
specify one or more typeclass constraints. The following
shows a simple lexer that makes use of this to interpret the
meaning of tokens using the Read
typeclass:
%wrapper "basic"
%token "Token s"
%typeclass "Read s"
tokens :-
[a-zA-Z0-9]+ { mkToken }
[ \t\r\n]+ ;
{
data Token s = Tok s
mkToken :: Read s => String -> Token s
mkToken = Tok . read
lex :: Read s => String -> [Token s]
lex = alexScanTokens
}
Multiple typeclasses can be given by separating them with commas, for example:
%typeclass "Read s, Eq s"
Type signatures can also be generated for lexers that do
not use any wrapper. Instead of the %token
directive, the %action directive is used to
specify the type of a lexer action. The
%typeclass directive can be used to specify
the typeclass in the same way as with a wrapper. The
following example shows the use of typeclasses with a
"homegrown" monadic lexer:
{
{-# LANGUAGE FlexibleContexts #-}
module Lexer where
import Control.Monad.State
import qualified Data.Bits
import Data.Word
}
%action "AlexInput -> Int -> m (Token s)"
%typeclass "Read s, MonadState AlexState m"
tokens :-
[a-zA-Z0-9]+ { mkToken }
[ \t\n\r]+ ;
{
alexEOF :: MonadState AlexState m => m (Token s)
alexEOF = return EOF
mkToken :: (Read s, MonadState AlexState m) =>
AlexInput -> Int -> m (Token s)
mkToken (_, _, _, s) len = return (Tok (read (take len s)))
data Token s = Tok s | EOF
lex :: (MonadState AlexState m, Read s) => String -> m (Token s)
lex input = alexMonadScan
-- "Boilerplate" code from monad wrapper has been omitted
}
The %token directive may only be used
with wrapper, and the %action can only be
used when no wrapper is used.
The %typeclass directive cannot be
given without the %token or
%action directive.