Parsec类似于many1,但如果结束则会失败

时间:2016-07-10 21:20:42

标签: haskell parsec

我正在经历Write Yourself a Scheme in 48 Hours而且我仍然坚持让数字正常运作。我希望以下内容解析十六进制数

parseOct :: Parser LispVal
parseOct = do
        char '#'
        char 'o'
        x <- many1 $ oneOf "01234567"
        return . Number . fst . head . readOct $ x

如果我以#o7为例,并按预期给我7,但是如果我给它#o78它不会失败而不是它给我{{1} }}。这似乎是因为很多人在没有匹配时会忽视任何事情。 Parsec中有什么东西可以让我获得所有的oct数字,但是如果它得到一个非oct字符,例如8,则会失败吗?

1 个答案:

答案 0 :(得分:2)

使用notFollowedBy确保没有字母数字遵循八进制数字:

import Text.Parsec
import Text.Parsec.Char
import Text.Parsec.String
import Text.Parsec.Combinator

parseOct' :: Parser String
parseOct' = do 
  char '#'
  char 'o'
  x <- many1 (oneOf "01234567")
  notFollowedBy alphaNum
  return x

test1 = parseTest parseOct' "#o123"
test2 = parseTest parseOct' "#o1238"

E.g:

*Main> test1
"123"
*Main> test2
parse error at (line 1, column 7):
unexpected '8'