gpt4 book ai didi

parsing - 如何使嵌套的 megaparsec 解析器失败?

转载 作者:行者123 更新时间:2023-12-04 03:24:41 24 4
gpt4 key购买 nike

我遇到了以下解析问题:

解析一些可能包含来自有限字符集的零个或多个元素的文本字符串,最多但不包括一组终止字符中的一个。应通过Maybe 指示内容/无内容。终止字符可能以转义形式出现在字符串中。任何不允许的字符解析都应该失败。

这是我想出的(简化):

import qualified Text.Megaparsec as MP

-- Predicate for admissible characters, not including the control characters.
isAdmissibleChar :: Char -> Bool
...

-- Predicate for control characters that need to be escaped.
isControlChar :: Char -> Bool
...

-- The escape character.
escChar :: Char
...


pComponent :: Parser (Maybe Text)
pComponent = do
t <- MP.many (escaped <|> regular)
if null t then return Nothing else return $ Just (T.pack t)
where
regular = MP.satisfy isAdmissibleChar <|> fail "Inadmissible character"
escaped = do
_ <- MC.char escChar
MP.satisfy isControlChar -- only control characters may be escaped

例如,允许的字符是大写 ASCII,转义字符是“\”,控制字符是“:”。然后,以下正确解析:ABC\:D:EF 生成 ABC:D。但是,解析 ABC&D,其中 & 是不允许的,确实会产生 ABC 而我希望得到一条错误消息。

两个问题:

  • 为什么 fail 结束解析而不是使解析器失败?
  • 上述方法是否可以解决问题,或者是否有一种“正确的”、规范的方法来解析我不知道的此类终止字符串?

最佳答案

many 必须允许其子解析器在没有整个解析的情况下失败一次失败 - 例如 many (char 'A') *> char 'B',在解析时“AAAB”,必须无法解析 B 才能知道它到达了结尾作为。

您可能需要 manyTill 来识别终止符明确地。像这样:

MP.manyTill (escaped <|> regular) (MP.satisfy isControlChar)

如果 isControlChar 不接受“&”,“ABC&D”会在此处给出错误。

或者如果你想解析多个组件,你可以保留你的pComponent 的现有定义并将其与 sepBy 或类似的方法一起使用,例如:

MP.sepBy pComponent (MP.satisfy isControlChar)

如果您在此之后还检查文件结尾,例如:

MP.sepBy pComponent (MP.satisfy isControlChar) <* MP.eof

那么 "ABC&D"应该会再次报错,因为 '&' 将结束第一个组件但不会被接受为分隔符。

关于parsing - 如何使嵌套的 megaparsec 解析器失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67809465/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com