为什么解析带有减号的字符串会失败?

时间:2012-09-28 15:19:16

标签: haskell parsec

为什么这会失败?

data Value = Num Integer
           | Str String

let numberOrString = (liftM Num (try int) <|> liftM Str (many1 (noneOf " "))
parse (numberOrString >> space)  "" "123-4 "

>> space是必需的。否则解析器将在123

之后停止

预期结果:

parse numberOrString "" "1234"
-> Num 1234

parse numberOrString "" "12-34"
-> Str "12-34"

结果:

parse numberOrString "" "1234-34 "
-> Left (line 1, column 5):
   unexpected "-"
   expecting digit or space

1 个答案:

答案 0 :(得分:4)

您没有给出int解析器组合器的定义,但我们假设它基本上需要一个或多个数字,前面可选地带有“ - ”(但只在前面!)。现在让我们来看看你的numberOrString解析器。

它解析一个整数文字,或者说是一个非空格字符串。在您的示例字符串上,解析器的第一个分支将成功,因为它会看到一串数字。它将在“ - ”字符前停止,因为这不是数字。现在,numberOrString >> space将失败,因为在一个数字之后,我们期望下一个字符是一个空格,“ - ”不是。

您基本上将解析器应用于两个整数文字字符串,一个正面和一个负面(或两个正面文字用“ - ”分隔,具体取决于您的语法)。这也是为什么单独应用numberOfString解析器只消耗“1234”的原因,因为这是它可以解析的最大整数文字。

编辑:我猜你想要的是try int失败,如果大多数数字字符串中有任何非数字字符。同样,这实际上取决于您对int的定义,但它可能被定义为一个解析器,它在至少一个未跟随字母字符的数字的任何字符串上成功。 int的通常定义将在数字字符串后面跟随非字母数字字符(例如“ - ”)成功,即使没有任何插入空格字符,因为这使得两个整数字面值和中缀运算符之间的空格可选。此外,它允许您成功解析“123)”,而无需编写“123)”。