More robust fi/done mixup reporting

This commit is contained in:
Vidar Holen
2012-11-26 23:50:00 -08:00
parent 2ea4711ff4
commit 8cf02e60af

View File

@@ -152,6 +152,9 @@ reluctantlyTill1 p end = do
attempting rest branch = do attempting rest branch = do
((try branch) >> rest) <|> rest ((try branch) >> rest) <|> rest
orFail parser stuff = do
try (disregard parser) <|> (disregard stuff >> fail "nope")
wasIncluded p = option False (p >> return True) wasIncluded p = option False (p >> return True)
acceptButWarn parser level note = do acceptButWarn parser level note = do
@@ -887,11 +890,11 @@ readIfClause = do
(condition, action) <- readIfPart (condition, action) <- readIfPart
elifs <- many readElifPart elifs <- many readElifPart
elses <- option [] readElsePart elses <- option [] readElsePart
g_Fi <|> (do
eof g_Fi `orFail` do
parseProblemAt pos ErrorC "Can't find 'fi' for this if. Make sure it's preceeded by a ; or \\n." parseProblemAt pos ErrorC "Couldn't find 'fi' for this 'if'."
fail "lol" parseProblem ErrorC "Expected 'fi' matching previously mentioned 'if'."
)
return $ T_IfExpression id ((condition, action):elifs) elses return $ T_IfExpression id ((condition, action):elifs) elses
readIfPart = do readIfPart = do
@@ -899,7 +902,9 @@ readIfPart = do
allspacing allspacing
pos <- getPosition pos <- getPosition
condition <- readTerm condition <- readTerm
g_Then g_Then `attempting` (do
try . lookAhead $ g_Do
parseProblem ErrorC "Perhaps you meant 'then'?")
acceptButWarn g_Semi ErrorC "No semicolons directly after 'then'." acceptButWarn g_Semi ErrorC "No semicolons directly after 'then'."
allspacing allspacing
action <- readTerm action <- readTerm
@@ -963,34 +968,19 @@ readUntilClause = do
readDoGroup = do readDoGroup = do
pos <- getPosition pos <- getPosition
g_Do optional (do
allspacing try . lookAhead $ g_Then
(eof >> return []) <|> parseProblem ErrorC "Perhaps you meant 'do'.")
do
commands <- readCompoundList
disregard g_Done <|> (do
eof
case hasFinal "done" commands of
Nothing -> parseProblemAt pos ErrorC "Couldn't find a 'done' for this 'do'."
Just (id) -> addNoteFor id $ Note ErrorC "Put a ; or \\n before the done."
)
return commands
<|> do
parseProblemAt pos ErrorC "Can't find the 'done' for this 'do'."
fail "No done"
hasFinal s [] = Nothing g_Do
hasFinal s f = acceptButWarn g_Semi ErrorC "No semicolons directly after 'do'."
case last f of allspacing
T_Pipeline _ m@(_:_) ->
case last m of commands <- readCompoundList
T_Redirecting _ [] (T_SimpleCommand _ _ m@(_:_)) -> g_Done `orFail` do
case last m of parseProblemAt pos ErrorC "Couldn't find 'done' for this 'do'."
T_NormalWord _ [T_Literal id str] -> parseProblem ErrorC "Expected 'done' matching previously mentioned 'do'."
if str == s then Just id else Nothing return commands
_ -> Nothing
_ -> Nothing
_ -> Nothing
prop_readForClause = isOk readForClause "for f in *; do rm \"$f\"; done" prop_readForClause = isOk readForClause "for f in *; do rm \"$f\"; done"
@@ -1233,7 +1223,7 @@ getStringFromParsec errors =
Message s -> (4, "Message: " ++ s) Message s -> (4, "Message: " ++ s)
wut "" = "eof" wut "" = "eof"
wut x = x wut x = x
unexpected s = "Aborting due to unexpected " ++ (wut s) ++ ". Is this even valid?" unexpected s = "Aborting due to unexpected " ++ (wut s) ++ ". Fix any mentioned problems and try again."
parseShell filename contents = do parseShell filename contents = do
case rp (parseWithNotes readScript) filename contents of case rp (parseWithNotes readScript) filename contents of