秒差距否定比对

时间:2019-01-26 14:32:45

标签: haskell parsec

parseIdent :: Parser (String)
parseIdent = do
  x <- lookAhead $ try $ many1 (choice [alphaNum])
  void $ optional endOfLine <|> eof
  case x of
    "macro" -> fail "illegal"
    _ -> pure x

我试图解析仅当与预定值不匹配(在这种情况下为macro时)才能成功的字母数字字符串。


但是,以下内容给我一个错误:

*** Exception: Text.ParserCombinators.Parsec.Prim.many: combinator 'many' is applied to a parser that accepts an empty string.

这没什么意义,many1 (choice [alphaNum])如何接受一个空字符串?


如果我移除lookAhead $ try,此错误就会消失。但是它与illegal“失败”:

...
*** Exception: (line 6, column 36):
unexpected " "
expecting letter or digit or new-line
illegal

我可以正确处理吗?还是有另一种实现否定搜索的技术?

1 个答案:

答案 0 :(得分:3)

您几乎拥有它:

import Text.Parsec
import Text.Parsec.Char
import Text.Parsec.String
import Control.Monad

parseIdent :: Parser (String)
parseIdent = try $ do
  x <- many1 alphaNum
  void $ optional endOfLine <|> eof
  case x of
    "macro" -> fail "illegal"
    _ -> pure x

那么,为什么您的代码不起作用?

  • try的位置错误。真正的回溯是在您返回字母数字词 并检查它不是"macro"
  • 之后的回溯
  • lookAhead在这里没有业务。如果最后得到所需的单词,则 do 希望从输入中使用该单词。 try已经负责将输入流重置为之前的状态