首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell (解析)代码无法理解它是如何工作的

Haskell (解析)代码无法理解它是如何工作的
EN

Stack Overflow用户
提问于 2021-12-06 23:51:30
回答 1查看 71关注 0票数 -1
代码语言:javascript
复制
openBr = char '['
closeBr = char ']'
openPn = char '('
closePn = char ')'
star = char '*'

myParser =
    (many1 star >>=
        \vs -> myParser >>=
            \x -> return (x+length vs)
    ) +++
        (openBr >>
            myParser >>=
                \c -> closeBr >>
                    myParser >>=
                        \d -> return (c+d)
        ) +++
            (openPn >>
                myParser >>=
                    \c -> closePn >>
                        myParser >>=
                            \d -> return (c+d)
            ) +++
                return 0
代码语言:javascript
复制
parse myParser "*(***[*(**)]*)*" 
-- outputs ([9,""])
parse myParser "*(***[*(**]*)*"
-- outputs ([1, "(***[*(**]*)*"])

当有一个匹配的括号和括号时,它会返回星星的数量,但是它会像第二个输出一样返回。我不明白代码是怎么工作的。有人能给我解释一下吗?

EN

回答 1

Stack Overflow用户

发布于 2021-12-07 21:58:52

首先,在编写这样的一元Haskell代码时,使用do notation是惯用的。这样可以减少噪音,使你的意图更清晰。

使用do符号重写的解析器如下所示:

代码语言:javascript
复制
myParser =
    -- run of stars
    (do
        vs <- many1 star
        x  <- myParser
        return (x+length vs)
    ) +++
    -- brackets
        (do
            openBr
            c <- myParser
            closeBr
            d <- myParser
            return (c+d)
        ) +++
    -- parentheses
            (do
                openPn
                c <- myParser
                closePn
                d <- myParser
                return (c+d)
            ) +++
    -- fail
                return 0

现在,当您解析第二个示例时,解析器将正确地解析第一个星号,并将总数增加到1,然后它会看到打开的括号,因此它选择了括号选择。

但是括号是不平衡的,因此括号解析器失败了,尽管它能够解析开括号后面的一些字符。这会导致泡沫上升的失败和整体解析的失败。当发生这种情况时,parse函数返回迄今累积的返回值,即故障前的星数,以及未解析的字符串的其余部分。

在这种情况下,您想要做的是使解析失败并返回0。因为解析库不会自动回溯,所以需要通过将子解析器封装在类库的等效try组合器中,显式地启用回溯。

哈斯克林快乐!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70253355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档