packages feed

Grempa-0.1.1: examples/Ex4StateLex.hs

{-# LANGUAGE TemplateHaskell, DeriveDataTypeable #-}
module Ex4StateLex
    ( Tok(..), lexToks
    ) where

import Data.Char
import Data.Data
import Language.Haskell.TH.Lift
import Data.Parser.Grempa.Static

-- | Token datatype
data Tok
    = Var {fromTok :: String}
    | Lambda
    | RightArrow
    | LParen | RParen
  deriving (Eq, Ord, Data, Typeable, Show, Read)

$(deriveLift ''Tok)
instance ToPat Tok where toPat = toConstrPat

-- | Do the lexing!
lexToks :: String -> [Tok]
lexToks [] = []
lexToks ('-':'>'        :as) | testHead (not . isSym) as = RightArrow : lexToks as
lexToks ('\\'            :as) = Lambda : lexToks as
lexToks ('('            :as) = LParen : lexToks as
lexToks (')'            :as) = RParen : lexToks as
lexToks as@(a:rest)
    | isLower a = go Var isId as
    | otherwise = lexToks rest

go :: (String -> Tok) -> (Char -> Bool) -> String -> [Tok]
go c p xs = let (v, rest) = span p xs in c v : lexToks rest

testHead :: (Char -> Bool) -> String -> Bool
testHead _ ""    = True
testHead f (a:_) = f a

isId :: Char -> Bool
isId c = isAlphaNum c || c == '_' || c == '\''

isSym :: Char -> Bool
isSym '(' = False
isSym ')' = False
isSym c   = isPunctuation c || isSymbol c