@@ -5,19 +5,37 @@ import public Text.Lexer.Core
5%default total
5%default total
6%access export
6%access export
8+||| Recognise any character
10+any = pred (const True)
12+||| Recognise a lexer or recognise no input. This is not guaranteed
14+opt : Lexer -> Recognise False
17+||| Recognise any character if the sub-lexer `l` fails.
18+non : (l : Lexer) -> Lexer
19+non l = reject l <+> any
21+||| Recognise the first matching lexer in a container. Always consumes input
22+||| if an option succeeds. Fails if the container is empty.
23+choice : Foldable t => t Lexer -> Lexer
24+choice xs = foldr (<|>) fail xs
8−||| Recognise a specific character
26+||| Recognise a specific character.
9is : Char -> Lexer
27is : Char -> Lexer
10is x = pred (==x)
28is x = pred (==x)
12−||| Recognise anything but the given character
30+||| Recognise anything but the given character.
13isNot : Char -> Lexer
31isNot : Char -> Lexer
14isNot x = pred (/=x)
32isNot x = pred (/=x)
16−||| Recognise a character case-insensitively
34+||| Recognise a specific character (case-insensitive).
17like : Char -> Lexer
35like : Char -> Lexer
18like x = pred (\y => toUpper x == toUpper y)
36like x = pred (\y => toUpper x == toUpper y)
20−||| Recognise anything but the given character case-insensitively
38+||| Recognise anything but the given character (case-insensitive).
21notLike : Char -> Lexer
39notLike : Char -> Lexer
22notLike x = pred (\y => toUpper x /= toUpper y)
40notLike x = pred (\y => toUpper x /= toUpper y)
@@ -35,24 +53,24 @@ approx str = case map like (unpack str) of
35 [] => fail
53 [] => fail
36 (x :: xs) => concat (x :: xs)
54 (x :: xs) => concat (x :: xs)
38−||| Recognise a lexer or recognise no input. This is not guaranteed
56+||| Recognise any of the characters in the given string
39−||| to consume input
57+oneOf : String -> Lexer
40−opt : Lexer -> Recognise False
58+oneOf cs = pred (\x => x `elem` unpack cs)
43−||| Recognise a sequence of at least one sub-lexers
60+||| Recognise a character range [`a`-`b`]. Also works in reverse!
44−some : Lexer -> Lexer
61+range : (start : Char) -> (end : Char) -> Lexer
45−some l = l <+> opt (some l)
62+range start end = pred (\x => (x >= min start end)
63+ && (x <= max start end))
47−||| Recognise a sequence of at zero or more sub-lexers. This is not
66+ ||| Recognise a sequence of at least one sub-lexers
48−||| guaranteed to consume input
67+ some : Lexer -> Lexer
49−many : Lexer -> Recognise False
68+ some l = l <+> many l
52−||| Recognise the first matching lexer from a Foldable. Always consumes input
70+ ||| Recognise a sequence of at zero or more sub-lexers. This is not
53−||| if one of the options succeeds. Fails if the foldable is empty.
71+ ||| guaranteed to consume input
54−choice : Foldable t => t Lexer -> Lexer
72+ many : Lexer -> Recognise False
55−choice xs = foldr (<|>) fail xs
73+ many l = opt (some l)
57||| Repeat the sub-lexer `l` zero or more times until the lexer
75||| Repeat the sub-lexer `l` zero or more times until the lexer
58||| `stopBefore` is encountered. `stopBefore` will not be consumed.
76||| `stopBefore` is encountered. `stopBefore` will not be consumed.
@@ -99,23 +117,6 @@ between (S min) (S max) l = l <+> between min max l
99exactly : (count : Nat) -> (l : Lexer) -> Recognise (count > 0)
117exactly : (count : Nat) -> (l : Lexer) -> Recognise (count > 0)
100exactly n l = between n n l
118exactly n l = between n n l
102−||| Recognise any character
104−any = pred (const True)
106−||| Recognise any character if the sub-lexer `l` fails.
107−non : (l : Lexer) -> Lexer
108−non l = reject l <+> any
110−||| Recognise any of the characters in the given string
111−oneOf : String -> Lexer
112−oneOf cs = pred (\x => x `elem` unpack cs)
114−||| Recognise a character range [`a`-`b`]. Also works in reverse!
115−range : (start : Char) -> (end : Char) -> Lexer
116−range start end = pred (\x => (x >= min start end)
117− && (x <= max start end))
119||| Recognise a single digit 0-9
120||| Recognise a single digit 0-9
120digit : Lexer
121digit : Lexer
121digit = pred isDigit
122digit = pred isDigit