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