Count unclosed parentheses, even after a complete expression.
Chris Pressey
6 months ago
35 | 35 |
A well-formed S-expression must have an opening parenthesis.
|
36 | 36 |
|
37 | 37 |
add)
|
38 | |
???> Unexpected characters
|
|
38 |
???> Incomplete expression
|
39 | 39 |
|
40 | 40 |
A well-formed S-expression must have an closing parenthesis.
|
41 | 41 |
|
42 | 42 |
(add
|
43 | |
???> Failed to parse
|
|
43 |
???> Incomplete expression
|
44 | 44 |
|
45 | 45 |
A well-formed S-expression does parse to an AST and thence to an ABT.
|
46 | 46 |
|
27 | 27 |
parse input =
|
28 | 28 |
if all isSpace input
|
29 | 29 |
then Error EmptyInput
|
30 | |
else case parseExpr (skipWhitespaceAndComments input) 0 of
|
31 | |
Right (result, rest, 0) -> Complete result rest
|
32 | |
Right (result, rest, count) -> Incomplete count input
|
|
30 |
else case parseFirstExpr (skipWhitespaceAndComments input) of
|
|
31 |
Right (result, rest) ->
|
|
32 |
-- After parsing a complete expression, check for any unclosed parens
|
|
33 |
case countUnclosedParens rest of
|
|
34 |
0 -> Complete result rest
|
|
35 |
n -> Incomplete n input
|
33 | 36 |
Left (UnmatchedOpenParen count) -> Incomplete count input
|
34 | 37 |
Left err -> Error err
|
|
38 |
|
|
39 |
-- Count unclosed parentheses in remaining input
|
|
40 |
countUnclosedParens :: String -> Int
|
|
41 |
countUnclosedParens = go 0
|
|
42 |
where
|
|
43 |
go count "" = count
|
|
44 |
go count (c:cs) = case c of
|
|
45 |
'(' -> go (count + 1) cs
|
|
46 |
')' -> go (count - 1) cs
|
|
47 |
_ -> go count cs
|
|
48 |
|
|
49 |
-- Parse first expression without paren counting
|
|
50 |
parseFirstExpr :: String -> Either ParseError (ConsList, String)
|
|
51 |
parseFirstExpr input = case parseExpr input 0 of
|
|
52 |
Right (result, rest, _) -> Right (result, rest)
|
|
53 |
Left err -> Left err
|
35 | 54 |
|
36 | 55 |
-- Expression parser now tracks paren count
|
37 | 56 |
parseExpr :: String -> Int -> Either ParseError (ConsList, String, Int)
|