packages feed

sexp-grammar-1.0.0: src/Language/Sexp/Lexer.x

{
{-# LANGUAGE BangPatterns #-}
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing     #-}
{-# OPTIONS_GHC -fno-warn-tabs               #-}
{-# OPTIONS_GHC -fno-warn-unused-binds       #-}
{-# OPTIONS_GHC -fno-warn-unused-imports     #-}
{-# OPTIONS_GHC -fno-warn-unused-matches     #-}

module Language.Sexp.Lexer
  ( lexSexp
  ) where

import qualified Data.Text as T
import Language.Sexp.Token
import Language.Sexp.Types (Position (..))
}

%wrapper "posn"

$whitechar   = [\ \t\n\r\f\v]

$digit       = 0-9
$hex         = [0-9 A-F a-f]
$alpha       = [a-z A-Z]

$graphic     = [$alpha $digit \!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~ \(\)\,\;\[\]\`\{\} \:\"\'\_]

@intnum      = [\-\+]? $digit+
@scinum      = [\-\+]? $digit+ ([\.]$digit+)? ([eE] [\-\+]? $digit+)?

$charesc     = [abfnrtv\\\"]
@escape      = \\ ($charesc | $digit+ | x $hex+)
@string      = $graphic # [\"\\] | " " | @escape

$idinitial   = [$alpha \!\$\%\&\*\/\<\=\>\?\~\_\^\.\+\-]
$idsubseq    = [$idinitial $digit \:]
@identifier  = $idinitial $idsubseq*
@keyword     = ":" $idsubseq+

:-

$whitechar+        ;
";".*              ;
"("                { just TokLParen                   }
")"                { just TokRParen                   }
"["                { just TokLBracket                 }
"]"                { just TokRBracket                 }
"'" / $graphic     { just TokQuote                    }
"#t"               { just (TokBool True)              }
"#f"               { just (TokBool False)             }
"#" / $graphic     { just TokHash                     }
@intnum            { TokInt     `via` readInteger     }
@scinum            { TokReal    `via` read            }
@identifier        { TokSymbol  `via` T.pack          }
@keyword           { TokKeyword `via` T.pack          }
\" @string* \"     { TokStr     `via` (T.pack . read) }
.                  { TokUnknown `via` head            }

{

readInteger :: String -> Integer
readInteger ('+': xs) = read xs
readInteger xs        = read xs

just :: Token -> AlexPosn -> String -> LocatedBy AlexPosn Token
just tok pos _ = L pos tok

via :: (a -> Token) -> (String -> a) -> AlexPosn -> String -> LocatedBy AlexPosn Token
via ftok f pos str = L pos (ftok (f str))

lexSexp :: FilePath -> String -> [LocatedBy Position Token]
lexSexp f = map (mapPosition fixPos) . alexScanTokens
  where
    fixPos (AlexPn _ l c) = Position l c

}