gpt4 book ai didi

haskell - 让 Parsec 函数失败而不是等待更多输入

转载 作者:行者123 更新时间:2023-12-02 18:02:24 26 4
gpt4 key购买 nike

我正在使用 Parsec 来解析一些表达式(请参阅 this question 了解更多上下文),我的代码中最相关的部分是:

statement :: Parser Stmt
statement = assignStmt <|> simpleStmt

assignStmt :: Parser Stmt
assignStmt =
do var <- identifier
reservedOp "="
expr <- expression
return $ Assign var expr

simpleStmt :: Parser Stmt
simpleStmt =
do expr <- expression
return $ Simple expr

实际操作:

boobla> foo = 100 + ~100
167
boobla> foo
parser error: (line 1, column 4):
unexpected end of input
expecting letter or digit or "="

第二个表达式的计算结果应为 167,即 foo 的值。

我认为当 Parsec 尝试提取 token reservedOp "=" 时,它应该失败,因为字符串中没有这样的 token ,然后尝试第二个函数 simpleStmt 并取得成功。但它的工作方式不同:它需要更多输入并抛出此异常。

如果字符串(或当前行)中没有更多字符,我应该使用什么来使 assignStmt 失败。 foo = 10 应使用 assignStmt 进行解析,foo 应使用 simpleStmt 进行解析。

最佳答案

您缺少try功能。

默认情况下,<|>运算符将尝试左侧解析器,如果失败但没有消耗任何字符,它将尝试右侧解析器。

但是,如果 - 就像您的情况一样 - 解析器在消耗了一些字符后失败,并且正确的解析器从未尝试过。请注意,这通常是您想要的行为;如果你有类似的东西

parseForLoop <|> parseWhileLoop

如果输入类似于“for break ”,那么这不是一个有效的 for 循环,并且尝试将其解析为 while 循环是没有意义的,因为这肯定也会失败。

try组合器改变了这种行为。具体来说,它使失败的解析器看起来没有消耗任何输入。 (这会造成空间损失;输入可能会被丢弃,但 try 让它徘徊。)

关于haskell - 让 Parsec 函数失败而不是等待更多输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26335793/

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