Text.Parsec many parser won't fully parse a custom parser

末鹿安然 提交于 2021-02-19 01:31:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!