packages feed

indents 0.2.0 → 0.3.0

raw patch · 2 files changed

+82/−117 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Text.Parsec.Indent: foldLine :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> b -> c) -> IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c
- Text.Parsec.Indent: foldLine3 :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> b -> c -> d) -> IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c -> IndentParserT s u m d
- Text.Parsec.Indent: foldLine4 :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> b -> c -> d -> e) -> IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c -> IndentParserT s u m d -> IndentParserT s u m e
- Text.Parsec.Indent: foldLine5 :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> b -> c -> d -> e -> f) -> IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c -> IndentParserT s u m d -> IndentParserT s u m e -> IndentParserT s u m f
- Text.Parsec.Indent: lineFold :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
- Text.Parsec.Indent: manyIndent :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
- Text.Parsec.Indent: manyLine :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
- Text.Parsec.Indent: withLineFold :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) -> IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c
- Text.Parsec.Indent: withLineFold' :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m [b]
+ Text.Parsec.Indent: (<*/>) :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ([a] -> b) -> IndentParserT s u m a -> IndentParserT s u m b
+ Text.Parsec.Indent: checkIndent :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
+ Text.Parsec.Indent: indentAngles :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a
+ Text.Parsec.Indent: indentBraces :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a
+ Text.Parsec.Indent: indentBrackets :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a
+ Text.Parsec.Indent: indentParens :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a
+ Text.Parsec.Indent: indented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
+ Text.Parsec.Indent: same :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
+ Text.Parsec.Indent: sameOrIndented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
+ Text.Parsec.Indent: withPos :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m a
- Text.Parsec.Indent: withBlock :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) -> IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c
+ Text.Parsec.Indent: withBlock :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) -> IndentParserT s u m a -> IndentParserT s u m x -> IndentParserT s u m b -> IndentParserT s u m c
- Text.Parsec.Indent: withBlock' :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m [b]
+ Text.Parsec.Indent: withBlock' :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m x -> IndentParserT s u m b -> IndentParserT s u m [b]

Files

Text/Parsec/Indent.hs view
@@ -1,96 +1,89 @@ {-# LANGUAGE FlexibleContexts #-} module Text.Parsec.Indent (-    IndentParserT,-    withBlock, withLineFold,-    withBlock', withLineFold',-    block, lineFold,-    manyLine, manyIndent,-    foldLine, foldLine3, foldLine4,-    foldLine5, (<+/>), (<-/>), runIndent+    -- $doc+    +    -- * Types+    IndentParserT, runIndent,+    -- * Blocks+    withBlock, withBlock', block,+    -- * Indentation Checking+    indented, same, sameOrIndented, checkIndent, withPos,+    -- * Paired characters+    indentBrackets, indentAngles, indentBraces, indentParens,+    -- * Line Fold Chaining+    -- | Any chain using these combinators must used with 'withPos'+    (<+/>), (<-/>), (<*/>)     ) where import Text.Parsec import Text.Parsec.Pos+import Text.Parsec.Token import Control.Monad.State import Control.Concatenative--{-| --A module to construct indentation aware parsers. Many programming-language have indentation based syntax rules e.g. python and Haskell.-This module exports combinators to create such parsers. --The input source can be thought of as a list of tokens. Abstractly-each token occurs at a line and a column and has a width. The column-number of a token measures is indentation. If t1 and t2 are two tokens-then we say that indentation of t1 is more than t2 if the column-number of occurrence of t1 is greater than that of t2.--Currently this module supports two kind of indentation based syntactic-structures which we now describe:--[Block] A block of indentation /c/ is a sequence of tokens with-indentation at least /c/.  Examples for a block is a where clause of-Haskell with no explicit braces.--[Line fold] A line fold starting at line /l/ and indentation /c/ is a-sequence of tokens that start at line /l/ and possibly continue to-subsequent lines as long as the indentation is greater than /c/. Such-a sequence of lines need to be /folded/ to a single line. An example-is MIME headers. Line folding based binding separation is used in-Haskell as well.+import Debug.Trace --}+-- $doc+-- A module to construct indentation aware parsers. Many programming+-- language have indentation based syntax rules e.g. python and Haskell.+-- This module exports combinators to create such parsers. +-- +-- The input source can be thought of as a list of tokens. Abstractly+-- each token occurs at a line and a column and has a width. The column+-- number of a token measures is indentation. If t1 and t2 are two tokens+-- then we say that indentation of t1 is more than t2 if the column+-- number of occurrence of t1 is greater than that of t2.+-- +-- Currently this module supports two kind of indentation based syntactic+-- structures which we now describe:+-- +-- [Block] A block of indentation /c/ is a sequence of tokens with+-- indentation at least /c/.  Examples for a block is a where clause of+-- Haskell with no explicit braces.+-- +-- [Line fold] A line fold starting at line /l/ and indentation /c/ is a+-- sequence of tokens that start at line /l/ and possibly continue to+-- subsequent lines as long as the indentation is greater than /c/. Such+-- a sequence of lines need to be /folded/ to a single line. An example+-- is MIME headers. Line folding based binding separation is used in+-- Haskell as well. +-- | Indentation sensitive parser type. Usually @ m @ will+--   be @ Identity @ as with any @ ParsecT @ type IndentParserT s u m a = ParsecT s u (StateT SourcePos m) a---- | @ 'withLineFold' f a p @ parses @ a @ followed by any number of @ p @---   that can wrap onto subsequent indented lines, combined by @ f @-withLineFold :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) ->-    IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c-withLineFold f a p = withPos $ do+    +-- | @ 'withBlock' f a b p @ parses @ a @ and optionally+--   @ b @ followed by an indented block of @ p @+--   , combining them with @ f @+withBlock :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) ->+    IndentParserT s u m a -> IndentParserT s u m x -> IndentParserT s u m b -> IndentParserT s u m c+withBlock f a b p = withPos $ do     r1 <- a-    r2 <- many (sameOrIndented >> p)+    r2 <- option [] (b >> indented >> block p)     return (f r1 r2) --- | Like 'withLineFold', but throws away initial parse result-withLineFold' :: (Stream s (StateT SourcePos m) Char, Monad m) =>-    IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m [b]-withLineFold' = withLineFold (flip const)- -- | Like 'withBlock', but throws away initial parse result withBlock' :: (Stream s (StateT SourcePos m) Char, Monad m) =>-    IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m [b]+    IndentParserT s u m a -> IndentParserT s u m x -> IndentParserT s u m b -> IndentParserT s u m [b] withBlock' = withBlock (flip const) --- | Parses one or more times, continuing in subsequent indented lines-lineFold :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]-lineFold = withLineFold' (return ())-    --- | @ 'withBlock' f a p @ parses @ a @ followed by an indented block of @ p @---   and combines them with @ f @-withBlock :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) ->-    IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c-withBlock f a p = withPos $ do-    r1 <- a-    r2 <- option [] (indented >> block p)-    return (f r1 r2)-+-- | Parses only when indented past the level of the reference indented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m () indented = do     pos <- getPosition     s <- get-    if biAp sourceColumn (<) pos s then mzero else do+    if biAp sourceColumn (<=) pos s then parserFail "not indented" else do         put $ setSourceLine s (sourceLine pos)         return () +-- | Parses only when indented past the level of the reference or on the same line sameOrIndented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m () sameOrIndented = same <|> indented +-- | Parses only on the same line as the reference same :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m () same = do     pos <- getPosition     s <- get-    if biAp sourceLine (==) pos s then return () else mzero+    if biAp sourceLine (==) pos s then return () else parserFail "over one line"      -- | Parses a block of lines at the same indentation level block :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]@@ -98,6 +91,7 @@     r <- many1 (checkIndent >> p)     return r +-- | Parses using the current location for indentation reference withPos :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m a withPos x = do     a <- get@@ -105,73 +99,44 @@     r <- put p >> x     put a >> return r +-- | Ensures the current indentation level matches that of the reference checkIndent :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m () checkIndent = do     s <- get     p <- getPosition-    if biAp sourceColumn (==) p s then return () else mzero+    if biAp sourceColumn (==) p s then return () else parserFail "indentation doesn't match"  -- | Run the result of an indentation sensitive parse runIndent :: Monad m => SourceName -> StateT SourcePos m a -> m a runIndent s = flip evalStateT (initialPos s) --- | Parses many occurances of p without using more than one line-manyLine :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]-manyLine p = withPos (many (same >> p))---- | Parses many occurances of p, indenting if over one line-manyIndent :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]-manyIndent p = withPos (many (sameOrIndented >> p))---- | Parses two arguments for @ f @ possibly wrapping onto subsequent lines-foldLine :: (Stream s (StateT SourcePos m) Char, Monad m) =>-    (a -> b -> c) -> IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c-foldLine f a b = withPos $ do-    r1 <- a-    r2 <- sameOrIndented >> b-    return $ f r1 r2---- | Parses three arguments for @ f @ possibly wrapping onto subsequent lines-foldLine3 :: (Stream s (StateT SourcePos m) Char, Monad m) =>-    (a -> b -> c -> d) -> IndentParserT s u m a -> IndentParserT s u m b-    -> IndentParserT s u m c -> IndentParserT s u m d-foldLine3 f a b c = withPos $ do-    r1 <- a-    r2 <- sameOrIndented >> b-    r3 <- sameOrIndented >> c-    return $ f r1 r2 r3---- | Parses four arguments for @ f @ possibly wrapping onto subsequent lines-foldLine4 :: (Stream s (StateT SourcePos m) Char, Monad m) =>-    (a -> b -> c -> d -> e) -> IndentParserT s u m a -> IndentParserT s u m b-    -> IndentParserT s u m c -> IndentParserT s u m d -> IndentParserT s u m e-foldLine4 f a b c d = withPos $ do-    r1 <- a-    r2 <- sameOrIndented >> b-    r3 <- sameOrIndented >> c-    r4 <- sameOrIndented >> d -    return $ f r1 r2 r3 r4---- | Parses four arguments for @ f @ possibly wrapping onto subsequent lines-foldLine5 :: (Stream s (StateT SourcePos m) Char, Monad m) =>-    (a -> b -> c -> d -> e -> f) -> IndentParserT s u m a -> IndentParserT s u m b-    -> IndentParserT s u m c -> IndentParserT s u m d -> IndentParserT s u m e-    -> IndentParserT s u m f-foldLine5 f a b c d e = withPos $ do-    r1 <- a-    r2 <- sameOrIndented >> b-    r3 <- sameOrIndented >> c-    r4 <- sameOrIndented >> d-    r5 <- sameOrIndented >> e-    return $ f r1 r2 r3 r4 r5---- | '<+/>' is to foldLine as 'ap' is to 'liftM2'+-- | '<+/>' is to indentation sensitive parsers what 'ap' is to monads (<+/>) :: (Stream s (StateT SourcePos m) Char, Monad m) =>     IndentParserT s u m (a -> b) -> IndentParserT s u m a -> IndentParserT s u m b-(<+/>) = foldLine id+a <+/> b = ap a (sameOrIndented >> b)  -- | '<-/>' is like '<+/>', but doesn't apply the function to the parsed value (<-/>) :: (Stream s (StateT SourcePos m) Char, Monad m) =>     IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m a-(<-/>) = foldLine const+a <-/> b = liftM2 const a (sameOrIndented >> b) +-- | Like '<+/>' but applies the second parser many times+(<*/>) :: (Stream s (StateT SourcePos m) Char, Monad m) =>+    IndentParserT s u m ([a] -> b) -> IndentParserT s u m a -> IndentParserT s u m b+a <*/> b = ap a (many (sameOrIndented >> b))++-- | parses with surrounding brackets+indentBrackets :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a+indentBrackets lexer p = withPos $ return id <-/> symbol lexer "[" <+/> p <-/> symbol lexer "]"++-- | parses with surrounding angle brackets+indentAngles :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a+indentAngles lexer p = withPos $ return id <-/> symbol lexer "<" <+/> p <-/> symbol lexer ">"++-- | parses with surrounding braces+indentBraces :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a+indentBraces lexer p = withPos $ return id <-/> symbol lexer "{" <+/> p <-/> symbol lexer "}"++-- | parses with surrounding parentheses +indentParens :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a+indentParens lexer p = withPos $ return id <-/> symbol lexer "(" <+/> p <-/> symbol lexer ")"
indents.cabal view
@@ -7,7 +7,7 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version:             0.2.0+Version:             0.3.0  -- A short (one-line) description of the package. Synopsis:            indentation sensitive parser-combinators for parsec