Merge pull request #280 from gallais/comments

[ fix #279 ] comment delimiters with more than one dash
This commit is contained in:
Edwin Brady 2020-04-21 10:49:24 +01:00 committed by GitHub
commit 8a0063a016
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 12 deletions

View File

@ -40,20 +40,58 @@ export
Show (TokenData Token) where
show t = show (line t, col t, tok t)
||| In `comment` we are careful not to parse closing delimiters as
||| valid comments. i.e. you may not write many dashes followed by
||| a closing brace and call it a valid comment.
comment : Lexer
comment = is '-' <+> is '-' <+> many (isNot '\n')
comment
= is '-' <+> is '-' -- comment opener
<+> many (is '-') <+> reject (is '}') -- not a closing delimiter
<+> many (isNot '\n') -- till the end of line
toEndComment : (k : Nat) -> Recognise (k /= 0)
toEndComment Z = empty
toEndComment (S k)
= some (pred (\c => c /= '-' && c /= '{' && c /= '"'))
<+> toEndComment (S k)
<|> is '{' <+> is '-' <+> toEndComment (S (S k))
<|> is '-' <+> is '}' <+> toEndComment k
<|> comment <+> toEndComment (S k)
<|> stringLit <+> toEndComment (S k)
<|> is '{' <+> toEndComment (S k)
<|> is '-' <+> toEndComment (S k)
mutual
||| The mutually defined functions represent different states in a
||| small automaton.
||| `toEndComment` is the default state and it will munch through
||| the input until we detect a special character (a dash, an
||| opening brace, or a double quote) and then switch to the
||| appropriate state.
toEndComment : (k : Nat) -> Recognise (k /= 0)
toEndComment Z = empty
toEndComment (S k)
= some (pred (\c => c /= '-' && c /= '{' && c /= '"'))
<+> toEndComment (S k)
<|> is '{' <+> singleBrace k
<|> is '-' <+> singleDash k
<|> stringLit <+> toEndComment (S k)
||| After reading a single brace, we may either finish reading an
||| opening delimiter or ignore it (e.g. it could be an implicit
||| binder).
singleBrace : (k : Nat) -> Lexer
singleBrace k
= is '-' <+> many (is '-') -- opening delimiter
<+> singleDash (S k) -- handles the {----} special case
<|> toEndComment (S k) -- not a valid comment
||| After reading a single dash, we may either find another one,
||| meaning we may have started reading a line comment, or find
||| a closing brace meaning we have found a closing delimiter.
singleDash : (k : Nat) -> Lexer
singleDash k
= is '-' <+> doubleDash k -- comment or closing delimiter
<|> is '}' <+> toEndComment k -- closing delimiter
<|> toEndComment (S k) -- not a valid comment
||| After reading a double dash, we are potentially reading a line
||| comment unless the series of uninterrupted dashes is ended with
||| a closing brace in which case it is a closing delimiter.
doubleDash : (k : Nat) -> Lexer
doubleDash k = many (is '-') <+> choice -- absorb all dashes
[ is '}' <+> toEndComment k -- closing delimiter
, many (isNot '\n') <+> toEndComment (S k) -- line comment
]
blockComment : Lexer
blockComment = is '{' <+> is '-' <+> toEndComment 1

View File

@ -1,3 +1,11 @@
{-------------------------}
-- These should be
-- ignored
{- {---------------} -}
-- Comments should have the right to be empty:
--
-- This is a valid comment {-
-- It should not lead to a parse error if nested in a
-- multiline comment
@ -21,3 +29,11 @@ myString = "Similarly, this is a valid string literal {- "
-- So we should be able to put it in a multiline comment
-}
{------------- Some people {---- like ---}
{- comments with
weird
----------}
closing delimiters
--}

View File

@ -0,0 +1,12 @@
module Main
{-- comment 1 --}
someFunction : IO ()
{-- comment 2 --}
main : IO ()
main = do
someFunction
pure ()

View File

@ -1,2 +1,4 @@
1/1: Building Comments (Comments.idr)
Main> Bye for now!
1/1: Building Issue279 (Issue279.idr)
Main> Bye for now!

View File

@ -1,3 +1,4 @@
echo ':q' | $1 --no-banner --no-prelude Comments.idr
echo ':q' | $1 --no-banner Issue279.idr
rm -rf build