{-| Quasi-quoters for "Text.Regex.TDFA" (extended POSIX) regular expressions. Refer to that module's documentation for more information on supported features. Quasi-quoters included in this module are: - 're' For splicing the expression to compile a regular expression AST to a 'Text.Regex.TDFA.Common.Regex' value. - 'pat' For splicing a regular expression AST of type 'Text.Regex.TDFA.Common.Pattern'. -} {-# LANGUAGE TemplateHaskell #-} module Text.Regex.TDFA.QuasiQuoter where import Prelude ( Either(..) , Maybe(..) , const , error , (++) , Eq(..) , break ) -- import Language.Haskell.TH.Quote ( QuasiQuoter(..) , dataToExpQ ) -- import Text.Regex.TDFA.TDFA ( patternToRegex ) -- import Text.Regex.TDFA.QuasiQuoter.Internal -- | Quasi-quoter for "Text.Regex.TDFA" (extended POSIX) regular -- expressions. Refer to that module's documentation for more -- information on supported features. -- -- See the documentation of 'unescape' for escape sequences this -- quasi-quoter supports. -- -- @[re|flags;regexp|]@ splices the expression to compile the AST -- (of type 'Text.Regex.TDFA.Common.Pattern') of @regexp@ using the -- 'Text.Regex.TDFA.Common.CompOption' and -- 'Text.Regex.TDFA.Common.ExecOption' indicated by @flags@. Incorrect -- flags or a failure to parse the regular expression is a -- compile-time error. -- -- Examples: -- -- - @[re|ga;a+b+c+|]@ has @flags = MCgRaN@ and @regexp = a+b+c+@. -- -- - @[re|;(z*)|]@ has @flags = MCGRaN@ and @regexp = (z*)@. -- -- Every flag name is assigned a unique upper and lower case letter pair. -- The uppercase letter indicates the flag to be True ("on"), and the -- lowercase letter indicates the flag to be False ("off"). -- -- @ -- Flag name | True | False | Default -- -------------------+--------+------------------- -- Multiline | M | m | M -- Case sensitive | C | c | C -- Capture groups | G | g | G -- Right associative | R | r | R -- Last star greedy | A | a | a -- New syntax | N | n | N -- @ -- -- Refer to 'Text.Regex.TDFA.Common.CompOption' and -- 'Text.Regex.TDFA.Common.ExecOption' for the meanings of each flag. -- -- For the significance of associativity see -- Section 3 "Types of failure". -- -- The default flags are 'MCGRaN'. Zero or more explicit flags must be -- specified in the @flags@ field. Explicit flags take precedence over -- default flags. Every explicit flag must occur at most once. If a -- flag is explicit the negated flag must not also be. -- re :: QuasiQuoter re = QuasiQuoter { quoteExp = quoter , quotePat = error "no quotePat" , quoteType = error "no quoteType" , quoteDec = error "no quoteDec" } where quoter txt = [e|patternToRegex $patternExp $compOptsExp $execOptsExp|] where (flagString, patternString) = case break (==';') txt of (flagString, ';':pat) -> (flagString, pat) _ -> error ("Regular expression format must be 'flags;regexp' " ++ "in '" ++ txt ++ "'") pattern = case compilePattern patternString of Right pat -> pat Left err -> error ("Error in regular expression '" ++ txt ++ "': " ++ err) options = case flagStringToOptions flagString of Right opts -> opts Left err -> error ("Error in regular expression '" ++ txt ++ "': " ++ err) (compOpts, execOpts) = optionsToTDFAOptions options patternExp = dataToExpQ (const Nothing) pattern compOptsExp = dataToExpQ (const Nothing) compOpts execOptsExp = dataToExpQ (const Nothing) execOpts -- -- | Quasi-quoter for "Text.Regex.TDFA" (extended POSIX) regular -- expressions. Refer to that module's documentation for more -- information on supported features. -- -- See the documentation of 'unescape' for escape sequences this -- quasi-quoter supports. -- -- @[pat|regexp]@ splices the AST (of type -- 'Text.Regex.TDFA.Pattern.Pattern') of @regexp@. A parse failure is a -- compile-time error. -- pat :: QuasiQuoter pat = QuasiQuoter { quoteExp = quoter , quotePat = error "no quotePat" , quoteType = error "no quoteType" , quoteDec = error "no quoteDec" } where quoter txt = dataToExpQ (const Nothing) pattern where pattern = case compilePattern txt of Right pat -> pat Left err -> error ("Error in regular expression '" ++ txt ++ "': " ++ err) --