3

我正在 Haskell 中编写 lambda 演算解析器,但找不到解决当前问题的解决方案。

我如何解析表达式:

expr :: Parser LamExpr
expr = do terms <- some $ token term
          return $ foldl1 LamApp terms

我如何解析术语:

term :: Parser LamExpr
term = do symbol "("
          e     <- expr
          symbol ")"
          return e

   <|> do symbol "\\"
          x     <- var
          symbol "->"
          e     <- expr
          return $ LamAbs x e

   <|> do {x <- var; return $ LamVar x}

   <|> do {name <- macroName; return $ LamMacro name}

在输入“x1 x2) x3”时,我的解析器返回

LamApp (LamVar 1) (LamVar 2)

解析应该失败,因为它在语法上不正确,但它仍然解析第一个应用程序。我认为这是因为do terms <- some $ token term它将尽可能多地解析,因为some.

我该如何解决这个问题,以便整个解析失败而不是一个部分?

4

1 回答 1

2

我假设您正在使用一些秒差变体。您只需在eof解析器的末尾添加一个。

parseInput = do
    e <- expr
    eof
    pure e  -- (*)

或者简而言之,使用Control.Applicative组合器:

parseInput = expr <* eof

(*) 顺便说一句,社区开始使用pure而不是return这些天

于 2021-01-10T22:22:04.667 回答