@@ -167,20 +167,35 @@ export
167symbol : Lexer
167symbol : Lexer
168symbol = some (pred (\x => not (isAlphaNum x) && not (isSpace x)))
168symbol = some (pred (\x => not (isAlphaNum x) && not (isSpace x)))
170−strChar : Lexer
170+||| Recognise zero or more occurrences of a sub-lexer between
171−strChar = (is '\\' <+> any) <|> isNot '"'
171+||| delimiting lexers
173+surround : (start : Lexer) -> (end : Lexer) -> (l : Lexer) -> Lexer
174+surround start end l = start <+> manyTill l end
176+||| Recognise zero or more occurrences of a sub-lexer surrounded
177+||| by the same quote lexer on both sides (useful for strings)
179+quote : (q : Lexer) -> (l : Lexer) -> Lexer
180+quote q l = surround q q l
182+||| Recognise an escape character (often '\\') followed by a sub-lexer
184+escape : (esc : Char) -> Lexer -> Lexer
185+escape esc l = is esc <+> l
173||| Recognise a string literal, including escaped characters.
187||| Recognise a string literal, including escaped characters.
174||| (Note: doesn't yet handle escape sequences such as \123)
188||| (Note: doesn't yet handle escape sequences such as \123)
176stringLit : Lexer
190stringLit : Lexer
177−stringLit = is '"' <+> many strChar <+> is '"'
191+stringLit = quote (is '"') (escape '\\' any <|> any)
179||| Recognise a character literal, including escaped characters.
193||| Recognise a character literal, including escaped characters.
180||| (Note: doesn't yet handle escape sequences such as \123)
194||| (Note: doesn't yet handle escape sequences such as \123)
182charLit : Lexer
196charLit : Lexer
183−charLit = is '\'' <+> strChar <+> is '\''
197+charLit = let q = '\'' in
198+ is q <+> (escape '\\' any <|> isNot q) <+> is q
185||| Recognise an integer literal (possibly with a '-' prefix)
200||| Recognise an integer literal (possibly with a '-' prefix)