~alcinnz/haskell-stylist

ref: fec99b19a7ca7886471d2e5554b7a1e21dbb2c98 haskell-stylist/src/Data/CSS/Syntax/StylishUtil.hs -rw-r--r-- 2.0 KiB
fec99b19 — Adrian Cochrane Add support for `@document regexp()`.. 3 years ago
                                                                                
186cbffa Adrian Cochrane
af343c17 Adrian Cochrane
c1fca3d5 Adrian Cochrane
ccae6742 Adrian Cochrane
c1fca3d5 Adrian Cochrane
186cbffa Adrian Cochrane
ccae6742 Adrian Cochrane
186cbffa Adrian Cochrane
ccae6742 Adrian Cochrane
c1fca3d5 Adrian Cochrane
186cbffa Adrian Cochrane
ccae6742 Adrian Cochrane
c1fca3d5 Adrian Cochrane
186cbffa Adrian Cochrane
ccae6742 Adrian Cochrane
c1fca3d5 Adrian Cochrane
186cbffa Adrian Cochrane
ccae6742 Adrian Cochrane
c1fca3d5 Adrian Cochrane
be4bb6f0 Adrian Cochrane
c1fca3d5 Adrian Cochrane
186cbffa Adrian Cochrane
ccae6742 Adrian Cochrane
c1fca3d5 Adrian Cochrane
186cbffa Adrian Cochrane
ccae6742 Adrian Cochrane
be4bb6f0 Adrian Cochrane
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
-- | Utility parser combinators for parsing CSS stylesheets.
module Data.CSS.Syntax.StylishUtil(
        concatP, capture, skipSpace,
        scanBlock, skipBlock, scanInner,
        Parser
    ) where

import Data.CSS.Syntax.Tokens

-- | A simple parser combinator type.
type Parser x = [Token] -> (x, [Token])

-- | Chains two parser combinators together.
concatP :: (a -> b -> c) -> Parser a -> Parser b -> Parser c
concatP join left right tokens = (join x y, remainder)
    where
        (x, tokens') = left tokens
        (y, remainder) = right tokens'

-- | "captures" the token being parsed into the returned output.
capture :: Parser [Token] -> Parser [Token]
capture cb (token:tokens) = (token:captured, tokens')
   where (captured, tokens') = cb tokens
capture _ [] = ([], [])

-- | Removes preceding `Whitespace` tokens.
skipSpace :: [Token] -> [Token]
skipSpace (Whitespace:tokens) = skipSpace tokens
skipSpace tokens = tokens

-- | Returns tokens until the next unbalanced closing brace.
scanBlock :: Parser [Token]
-- TODO assert closing tags are correct
--    But what should the error recovery be?
scanBlock (RightCurlyBracket:tokens) = ([RightCurlyBracket], tokens)
scanBlock (RightParen:tokens) = ([RightParen], tokens)
scanBlock (RightSquareBracket:tokens) = ([RightSquareBracket], tokens)

scanBlock tokens@(LeftCurlyBracket:_) = scanInner tokens scanBlock
scanBlock tokens@(LeftParen:_) = scanInner tokens scanBlock
scanBlock tokens@(Function _:_) = scanInner tokens scanBlock
scanBlock tokens@(LeftSquareBracket:_) = scanInner tokens scanBlock

scanBlock tokens = capture scanBlock tokens

-- | Returns tokens after the next unbalanced closing brace.
skipBlock :: [Token] -> [Token]
skipBlock tokens = snd $ scanBlock tokens

-- | Parses a block followed by the given combinator, returning the tokens the matched.
scanInner :: [Token] -> Parser [Token] -> ([Token], [Token])
scanInner (token:tokens) cb = concatP gather scanBlock cb tokens
    where gather x y = token : x ++ y
scanInner [] _ = error "Expected a token to capture."