trifecta 0.19 → 0.20
raw patch · 6 files changed
+270/−132 lines, 6 files
Files
- Text/Trifecta/Diagnostic.hs +2/−0
- Text/Trifecta/Diagnostic/Class.hs +33/−0
- Text/Trifecta/Parser.hs +6/−0
- Text/Trifecta/Parser/Literals.hs +212/−0
- Text/Trifecta/Parser/Token/Combinators.hs +11/−128
- trifecta.cabal +6/−4
Text/Trifecta/Diagnostic.hs view
@@ -1,6 +1,7 @@ module Text.Trifecta.Diagnostic ( Diagnostic(..) , tellDiagnostic+ , MonadDiagnostic(..) , DiagnosticLevel(..) , Renderable(..) , Source@@ -11,5 +12,6 @@ ) where import Text.Trifecta.Diagnostic.Prim+import Text.Trifecta.Diagnostic.Class import Text.Trifecta.Diagnostic.Level import Text.Trifecta.Diagnostic.Rendering
+ Text/Trifecta/Diagnostic/Class.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies, FlexibleContexts, UndecidableInstances #-}+module Text.Trifecta.Diagnostic.Class+ ( MonadDiagnostic(..)+ ) where++import Control.Monad.Trans.Class+import Control.Monad.Trans.State.Lazy as Lazy+import Control.Monad.Trans.State.Strict as Strict+import Text.Trifecta.Diagnostic.Prim++class Monad m => MonadDiagnostic e m | m -> e where+ record :: Diagnostic e -> m a+ fatal :: e -> m a -- consuming error+ err :: e -> m a -- non-consuming error+ warn :: e -> m ()+ note :: e -> m ()+ verbose :: Int -> e -> m ()++instance MonadDiagnostic e m => MonadDiagnostic e (Lazy.StateT s m) where+ record = lift . record+ fatal = lift . fatal+ err = lift . err+ warn = lift . warn+ note = lift . note+ verbose n = lift . verbose n++instance MonadDiagnostic e m => MonadDiagnostic e (Strict.StateT s m) where+ record = lift . record+ fatal = lift . fatal+ err = lift . err+ warn = lift . warn+ note = lift . note+ verbose n = lift . verbose n
Text/Trifecta/Parser.hs view
@@ -5,6 +5,11 @@ , module Text.Trifecta.Parser.Combinators , module Text.Trifecta.Parser.Token , module Text.Trifecta.Parser.Result+ -- * traditional numeric literals that would be in Token+ , decimal+ , hexadecimal+ , octal+ -- * expressive diagnostics , caret , careted , span@@ -16,6 +21,7 @@ import Text.Trifecta.Parser.Class import Text.Trifecta.Parser.Char import Text.Trifecta.Parser.Combinators+import Text.Trifecta.Parser.Literals import Text.Trifecta.Parser.Token import Text.Trifecta.Parser.Result
+ Text/Trifecta/Parser/Literals.hs view
@@ -0,0 +1,212 @@+-----------------------------------------------------------------------------+-- |+-- Module : Text.Trifecta.Parser.Literals+-- Copyright : (c) Edward Kmett 2011,+-- (c) Daan Leijen 1999-2001+-- License : BSD3+-- +-- Maintainer : ekmett@gmail.com+-- Stability : provisional+-- Portability : non-portable+-- +-----------------------------------------------------------------------------+module Text.Trifecta.Parser.Literals+ ( charLiteral'+ , stringLiteral'+ , natural'+ , integer'+ , double'+ , naturalOrDouble'+ , decimal+ , hexadecimal+ , octal+ ) where++import Data.Char (digitToInt)+import Control.Applicative+import Text.Trifecta.Parser.Class+import Text.Trifecta.Parser.Char+import Text.Trifecta.Parser.Combinators++-- | This parser parses a single literal character. Returns the+-- literal character value. This parsers deals correctly with escape+-- sequences. The literal character is parsed according to the grammar+-- rules defined in the Haskell report (which matches most programming+-- languages quite closely). +--+-- This parser does NOT swallow trailing whitespace. +charLiteral' :: MonadParser m => m Char+charLiteral' = between (char '\'') (char '\'' <?> "end of character") characterChar+ <?> "character" ++characterChar, charEscape, charLetter :: MonadParser m => m Char+characterChar = charLetter <|> charEscape+ <?> "literal character"+charEscape = char '\\' *> escapeCode+charLetter = satisfy (\c -> (c /= '\'') && (c /= '\\') && (c > '\026'))++-- | This parser parses a literal string. Returns the literal+-- string value. This parsers deals correctly with escape sequences and+-- gaps. The literal string is parsed according to the grammar rules+-- defined in the Haskell report (which matches most programming+-- languages quite closely). +--+-- This parser does NOT swallow trailing whitespace+stringLiteral' :: MonadParser m => m String+stringLiteral' = lit where+ lit = foldr (maybe id (:)) "" <$> between (char '"') (char '"' <?> "end of string") (many stringChar) + <?> "literal string"+ stringChar = Just <$> stringLetter + <|> stringEscape + <?> "string character"+ stringLetter = satisfy (\c -> (c /= '"') && (c /= '\\') && (c > '\026'))++ stringEscape = char '\\' *> esc where+ esc = Nothing <$ escapeGap + <|> Nothing <$ escapeEmpty + <|> Just <$> escapeCode+ escapeEmpty = char '&'+ escapeGap = do skipSome space+ char '\\' <?> "end of string gap"++escapeCode :: MonadParser m => m Char+escapeCode = (charEsc <|> charNum <|> charAscii <|> charControl) <?> "escape code"+ where + charControl = (\c -> toEnum (fromEnum c - fromEnum 'A')) <$> (char '^' *> upper)+ charNum = toEnum . fromInteger <$> num where+ num = decimal + <|> (char 'o' *> number 8 octDigit)+ <|> (char 'x' *> number 16 hexDigit)+ charEsc = choice $ parseEsc <$> escMap+ parseEsc (c,code) = code <$ char c+ escMap = zip ("abfnrtv\\\"\'") ("\a\b\f\n\r\t\v\\\"\'")+ charAscii = choice $ parseAscii <$> asciiMap+ parseAscii (asc,code) = try $ code <$ string asc+ asciiMap = zip (ascii3codes ++ ascii2codes) (ascii3 ++ ascii2)+ ascii2codes, ascii3codes :: [String]+ ascii2codes = [ "BS","HT","LF","VT","FF","CR","SO"+ , "SI","EM","FS","GS","RS","US","SP"]+ ascii3codes = ["NUL","SOH","STX","ETX","EOT","ENQ","ACK"+ ,"BEL","DLE","DC1","DC2","DC3","DC4","NAK"+ ,"SYN","ETB","CAN","SUB","ESC","DEL"]+ ascii2, ascii3 :: [Char]+ ascii2 = ['\BS','\HT','\LF','\VT','\FF','\CR','\SO','\SI'+ ,'\EM','\FS','\GS','\RS','\US','\SP']+ ascii3 = ['\NUL','\SOH','\STX','\ETX','\EOT','\ENQ','\ACK'+ ,'\BEL','\DLE','\DC1','\DC2','\DC3','\DC4','\NAK'+ ,'\SYN','\ETB','\CAN','\SUB','\ESC','\DEL']+ ++-- | This lexeme parser parses a natural number (a positive whole+-- number). Returns the value of the number. The number can be+-- specified in 'decimal', 'hexadecimal' or+-- 'octal'. The number is parsed according to the grammar+-- rules in the Haskell report. +--+-- This parser does NOT swallow trailing whitespace. +natural' :: MonadParser m => m Integer+natural' = nat <?> "natural"++number :: MonadParser m => Integer -> m Char -> m Integer+number base baseDigit = do+ digits <- some baseDigit+ return $! foldl (\x d -> base*x + toInteger (digitToInt d)) 0 digits++-- | This lexeme parser parses an integer (a whole number). This parser+-- is like 'natural' except that it can be prefixed with+-- sign (i.e. \'-\' or \'+\'). Returns the value of the number. The+-- number can be specified in 'decimal', 'hexadecimal'+-- or 'octal'. The number is parsed according+-- to the grammar rules in the Haskell report. +--+-- This parser does NOT swallow trailing whitespace. +--+-- Also, unlike the 'integer' parser, this parser does not admit spaces+-- between the sign and the number.+ +integer' :: MonadParser m => m Integer+integer' = int <?> "integer"++sign :: MonadParser m => m (Integer -> Integer)+sign = negate <$ char '-'+ <|> id <$ char '+'+ <|> pure id++int :: MonadParser m => m Integer+int = {-lexeme-} sign <*> nat+nat, zeroNumber :: MonadParser m => m Integer+nat = zeroNumber <|> decimal+zeroNumber = char '0' *> (hexadecimal <|> octal <|> decimal <|> return 0) <?> ""++-- | This parser parses a floating point value. Returns the value+-- of the number. The number is parsed according to the grammar rules+-- defined in the Haskell report. +--+-- This parser does NOT swallow trailing whitespace. ++double' :: MonadParser m => m Double+double' = floating <?> "double"++floating :: MonadParser m => m Double+floating = decimal >>= fractExponent++fractExponent :: MonadParser m => Integer -> m Double+fractExponent n = (\fract expo -> (fromInteger n + fract) * expo) <$> fraction <*> option 1.0 exponent'+ <|> (fromInteger n *) <$> exponent' where+ fraction = foldr op 0.0 <$> (char '.' *> (some digit <?> "fraction"))+ op d f = (f + fromIntegral (digitToInt d))/10.0+ exponent' = do+ _ <- oneOf "eE"+ f <- sign+ e <- decimal <?> "exponent"+ return (power (f e))+ <?> "exponent"+ power e + | e < 0 = 1.0/power(-e)+ | otherwise = fromInteger (10^e)++-- | This parser parses either 'natural' or a 'float'.+-- Returns the value of the number. This parsers deals with+-- any overlap in the grammar rules for naturals and floats. The number+-- is parsed according to the grammar rules defined in the Haskell report. +--+-- This parser does NOT swallow trailing whitespace. ++naturalOrDouble' :: MonadParser m => m (Either Integer Double)+naturalOrDouble' = natDouble <?> "number"++natDouble, zeroNumFloat, decimalFloat :: MonadParser m => m (Either Integer Double)+natDouble + = char '0' *> zeroNumFloat+ <|> decimalFloat+zeroNumFloat+ = Left <$> (hexadecimal <|> octal)+ <|> decimalFloat+ <|> fractFloat 0+ <|> return (Left 0)+decimalFloat = do + n <- decimal+ option (Left n) (fractFloat n)++fractFloat :: MonadParser m => Integer -> m (Either Integer Double)+fractFloat n = Right <$> fractExponent n++-- | Parses a positive whole number in the decimal system. Returns the+-- value of the number. ++decimal :: MonadParser m => m Integer+decimal = number 10 digit++-- | Parses a positive whole number in the hexadecimal system. The number+-- should be prefixed with \"0x\" or \"0X\". Returns the value of the+-- number. ++hexadecimal :: MonadParser m => m Integer+hexadecimal = oneOf "xX" *> number 16 hexDigit++-- | Parses a positive whole number in the octal system. The number+-- should be prefixed with \"0o\" or \"0O\". Returns the value of the+-- number. ++octal :: MonadParser m => m Integer+octal = oneOf "oO" *> number 8 octDigit
Text/Trifecta/Parser/Token/Combinators.hs view
@@ -17,9 +17,6 @@ , integer , double , naturalOrDouble- , decimal- , hexadecimal- , octal , symbol , symbolic , parens@@ -36,11 +33,11 @@ , commaSep1 ) where -import Data.Char (digitToInt) import Data.ByteString as Strict hiding (map, zip, foldl, foldr) import Control.Applicative import Text.Trifecta.Parser.Class import Text.Trifecta.Parser.Char+import Text.Trifecta.Parser.Literals import Text.Trifecta.Parser.Combinators import Text.Trifecta.Parser.Token.Class @@ -50,14 +47,7 @@ -- rules defined in the Haskell report (which matches most programming -- languages quite closely). charLiteral :: MonadTokenParser m => m Char-charLiteral = lexeme (between (char '\'') (char '\'' <?> "end of character") characterChar)- <?> "character" --characterChar, charEscape, charLetter :: MonadTokenParser m => m Char-characterChar = charLetter <|> charEscape- <?> "literal character"-charEscape = char '\\' *> escapeCode-charLetter = satisfy (\c -> (c /= '\'') && (c /= '\\') && (c > '\026'))+charLiteral = lexeme charLiteral' -- | This lexeme parser parses a literal string. Returns the literal -- string value. This parsers deals correctly with escape sequences and@@ -66,49 +56,7 @@ -- languages quite closely). stringLiteral :: MonadTokenParser m => m String-stringLiteral = lexeme lit where- lit = foldr (maybe id (:)) "" <$> between (char '"') (char '"' <?> "end of string") (many stringChar) - <?> "literal string"- stringChar = Just <$> stringLetter - <|> stringEscape - <?> "string character"- stringLetter = satisfy (\c -> (c /= '"') && (c /= '\\') && (c > '\026'))-- stringEscape = char '\\' *> esc where- esc = Nothing <$ escapeGap - <|> Nothing <$ escapeEmpty - <|> Just <$> escapeCode- escapeEmpty = char '&'- escapeGap = do skipSome space- char '\\' <?> "end of string gap"--escapeCode :: MonadTokenParser m => m Char-escapeCode = (charEsc <|> charNum <|> charAscii <|> charControl) <?> "escape code"- where - charControl = (\c -> toEnum (fromEnum c - fromEnum 'A')) <$> (char '^' *> upper)- charNum = toEnum . fromInteger <$> num where- num = decimal - <|> (char 'o' *> number 8 octDigit)- <|> (char 'x' *> number 16 hexDigit)- charEsc = choice $ parseEsc <$> escMap- parseEsc (c,code) = code <$ char c- escMap = zip ("abfnrtv\\\"\'") ("\a\b\f\n\r\t\v\\\"\'")- charAscii = choice $ parseAscii <$> asciiMap- parseAscii (asc,code) = try $ code <$ string asc- asciiMap = zip (ascii3codes ++ ascii2codes) (ascii3 ++ ascii2)- ascii2codes, ascii3codes :: [String]- ascii2codes = [ "BS","HT","LF","VT","FF","CR","SO"- , "SI","EM","FS","GS","RS","US","SP"]- ascii3codes = ["NUL","SOH","STX","ETX","EOT","ENQ","ACK"- ,"BEL","DLE","DC1","DC2","DC3","DC4","NAK"- ,"SYN","ETB","CAN","SUB","ESC","DEL"]- ascii2, ascii3 :: [Char]- ascii2 = ['\BS','\HT','\LF','\VT','\FF','\CR','\SO','\SI'- ,'\EM','\FS','\GS','\RS','\US','\SP']- ascii3 = ['\NUL','\SOH','\STX','\ETX','\EOT','\ENQ','\ACK'- ,'\BEL','\DLE','\DC1','\DC2','\DC3','\DC4','\NAK'- ,'\SYN','\ETB','\CAN','\SUB','\ESC','\DEL']- +stringLiteral = lexeme stringLiteral' -- | This lexeme parser parses a natural number (a positive whole -- number). Returns the value of the number. The number can be@@ -117,12 +65,7 @@ -- rules in the Haskell report. natural :: MonadTokenParser m => m Integer-natural = lexeme nat <?> "natural"--number :: MonadTokenParser m => Integer -> m Char -> m Integer-number base baseDigit = do- digits <- some baseDigit- return $! foldl (\x d -> base*x + toInteger (digitToInt d)) 0 digits+natural = lexeme natural' -- | This lexeme parser parses an integer (a whole number). This parser -- is like 'natural' except that it can be prefixed with@@ -133,41 +76,18 @@ integer :: MonadTokenParser m => m Integer integer = lexeme int <?> "integer"--sign :: MonadTokenParser m => m (Integer -> Integer)-sign = negate <$ char '-'- <|> id <$ char '+'- <|> pure id--nat, int, zeroNumber :: MonadTokenParser m => m Integer-nat = zeroNumber <|> decimal-int = lexeme sign <*> nat-zeroNumber = char '0' *> (hexadecimal <|> octal <|> decimal <|> return 0) <?> ""+ where+ sign = negate <$ char '-'+ <|> id <$ char '+'+ <|> pure id+ int = lexeme sign <*> natural' -- | This lexeme parser parses a floating point value. Returns the value -- of the number. The number is parsed according to the grammar rules -- defined in the Haskell report. double :: MonadTokenParser m => m Double-double = lexeme floating <?> "double"--floating :: MonadTokenParser m => m Double-floating = decimal >>= fractExponent--fractExponent :: MonadTokenParser m => Integer -> m Double-fractExponent n = (\fract expo -> (fromInteger n + fract) * expo) <$> fraction <*> option 1.0 exponent'- <|> (fromInteger n *) <$> exponent' where- fraction = foldr op 0.0 <$> (char '.' *> (some digit <?> "fraction"))- op d f = (f + fromIntegral (digitToInt d))/10.0- exponent' = do- _ <- oneOf "eE"- f <- sign- e <- decimal <?> "exponent"- return (power (f e))- <?> "exponent"- power e - | e < 0 = 1.0/power(-e)- | otherwise = fromInteger (10^e)+double = lexeme double' -- | This lexeme parser parses either 'natural' or a 'float'. -- Returns the value of the number. This parsers deals with@@ -175,43 +95,7 @@ -- is parsed according to the grammar rules defined in the Haskell report. naturalOrDouble :: MonadTokenParser m => m (Either Integer Double)-naturalOrDouble = lexeme natDouble <?> "number"--natDouble , zeroNumFloat, decimalFloat :: MonadTokenParser m => m (Either Integer Double)-natDouble - = char '0' *> zeroNumFloat- <|> decimalFloat-zeroNumFloat- = Left <$> (hexadecimal <|> octal)- <|> decimalFloat- <|> fractFloat 0- <|> return (Left 0)-decimalFloat = do - n <- decimal- option (Left n) (fractFloat n)--fractFloat :: MonadTokenParser m => Integer -> m (Either Integer Double)-fractFloat n = Right <$> fractExponent n---- | Parses a positive whole number in the decimal system. Returns the--- value of the number. --decimal :: MonadTokenParser m => m Integer-decimal = number 10 digit---- | Parses a positive whole number in the hexadecimal system. The number--- should be prefixed with \"0x\" or \"0X\". Returns the value of the--- number. --hexadecimal :: MonadTokenParser m => m Integer-hexadecimal = oneOf "xX" *> number 16 hexDigit---- | Parses a positive whole number in the octal system. The number--- should be prefixed with \"0o\" or \"0O\". Returns the value of the--- number. --octal :: MonadTokenParser m => m Integer-octal = oneOf "oO" *> number 8 octDigit+naturalOrDouble = lexeme naturalOrDouble' -- | Lexeme parser @symbol s@ parses 'string' @s@ and skips -- trailing white space. @@ -230,7 +114,6 @@ parens :: MonadTokenParser m => m a -> m a parens = between (symbolic '(') (symbolic ')')- -- | Lexeme parser @braces p@ parses @p@ enclosed in braces (\'{\' and -- \'}\'), returning the value of @p@.
trifecta.cabal view
@@ -1,6 +1,6 @@ name: trifecta category: Text, Parsing, Diagnostics, Pretty Printer, Logging-version: 0.19+version: 0.20 license: BSD3 cabal-version: >= 1.6 license-file: LICENSE@@ -37,6 +37,7 @@ Text.Trifecta.Rope.Strand Text.Trifecta.Diagnostic Text.Trifecta.Diagnostic.Prim+ Text.Trifecta.Diagnostic.Class Text.Trifecta.Diagnostic.Level Text.Trifecta.Diagnostic.Err Text.Trifecta.Diagnostic.Err.State@@ -46,13 +47,14 @@ Text.Trifecta.Diagnostic.Rendering.Fixit Text.Trifecta.Diagnostic.Rendering.Span Text.Trifecta.Parser- Text.Trifecta.Parser.It Text.Trifecta.Parser.Char- Text.Trifecta.Parser.Expr Text.Trifecta.Parser.Class+ Text.Trifecta.Parser.Combinators+ Text.Trifecta.Parser.Expr+ Text.Trifecta.Parser.It+ Text.Trifecta.Parser.Literals Text.Trifecta.Parser.Prim Text.Trifecta.Parser.Result- Text.Trifecta.Parser.Combinators Text.Trifecta.Parser.Step Text.Trifecta.Parser.Token Text.Trifecta.Parser.Token.Class