on master help sign in
Text.Lexer: add `manyUntil` and `manyThen`

These new functions utilise lookahead to non-greedily consume a sub-lexer until an endpoint lexer is recognised. `manyUntil` does not consume the end lexer, and `manyThen` does.

commit7e604f86fa0691e5c66f227ea0836aeb55d7792e authorMichael Morgan <morgan.michael@me.com> dateSat 2 Sep 2017, 20:53 (9 years ago) parent82a82ab
1 file changed+15−1
libs/contrib/Text/Lexer.idr+15−1
libs/contrib/Text/Lexer.idr+15−1
@@ -119,6 +119,20 @@ choice : (xs : List Lexer) -> {auto ok : NonEmpty xs} -> Lexer
119119choice (x :: []) = x
120120choice (x :: xs@(_ :: _)) = x <|> choice xs
121121
122+||| Repeat the sub-lexer `l` zero or more times until the lexer
123+||| `stopBefore` is encountered. `stopBefore` will not be consumed.
124+||| Not guaranteed to consume input.
125+export
126+manyUntil : (stopBefore : Recognise c) -> (l : Lexer) -> Recognise False
127+manyUntil stopBefore l = many (reject stopBefore <+> l)
128+
129+||| Repeat the sub-lexer `l` zero or more times until the lexer
130+||| `stopAfter` is encountered, and consume it. Guaranteed to
131+||| consume if `stopAfter` consumes.
132+export
133+manyThen : (stopAfter : Recognise c) -> (l : Lexer) -> Recognise c
134+manyThen stopAfter l = manyUntil stopAfter l <+> stopAfter
135+
122136||| Recognise many instances of `l` until an instance of `end` is
123137||| encountered.
124138|||
@@ -291,7 +305,7 @@ symbols = some symbol
291305||| delimiting lexers
292306export
293307surround : (start : Lexer) -> (end : Lexer) -> (l : Lexer) -> Lexer
294−surround start end l = start <+> many (reject end <+> l) <+> end
308+surround start end l = start <+> manyThen end l
295309
296310||| Recognise zero or more occurrences of a sub-lexer surrounded
297311||| by the same quote lexer on both sides (useful for strings)