问题
I'm having an issue in which my parser for if-blocks (and Do-While blocks because the problem is the same) won't terminate upon the parsing of the string "fi". An If-Block takes the form of:
if P -> p
[] Q -> q
fi
If I use Text.Parsec
's string parser to parse "fi"
like how I used it to parse "if"
to even enter the loop, the program halts. When I print out what should be evaluated its not even there so the program doesn't even enter the If-Block when it is ended with "fi"
.
When I remove the parser that parses "fi"
however, what occurs is that the program can run and the evaluation of the If-Block is as expected but I have to end the block with the same number of "fi"
(or any string) as expressions within the block itself. If I don't end the block with the same number of "fi"
's, what happens is any statement after the block is evaluated infinitely. For example, a block which adds one to a running total if a variable is even would look like:
if ((x mod 2) = 0)-> r := r + 1
[] ((x mod 2) = 1)-> r := r + 0
fi
fi
And if there was a single "fi"
, and I printed the value of r after the block, it would print r infinitely
if ((x mod 2) = 0)-> r := r + 1
[] ((x mod 2) = 1)-> r := r + 0
fi
print(r)
./Main prog
1
1
1
1
1
...
The issue is probably a misuse of the spaces
function but I can't seem to get the parsing correct even when I remove all of the instances of spaces such that everything is on a single line concatenated together. Even when I do that, it won't accept "fi"
in the Parser code but it will accept it if it's the same number as expressions when its removed.
parseIf :: Parser HStatement
parseIf = do
try (string "if") <|> try (string "[]")
spaces
string "("
cond <- parseVals
string ")->"
spaces
expr <- many1 $ parseStatements
spaces
return $ If (cond, expr)
parseSelection :: Parser HStatement
parseSelection = do
selection <- many1 parseIf
spaces
--try (string "fi")
return $ Selection selection
parseStatements :: Parser HStatement
parseStatements = try (parseDo) <* spaces <|> try (parseSelection) <|> try (parsePrint) <|> try (parseEvalHVal)
来源:https://stackoverflow.com/questions/65704097/text-parsec-many-parser-wont-fully-parse-a-custom-parser