Parsec - 罗马数字 - 当我改变顺序时,即使尝试也不解析

时间:2014-11-29 09:28:38

标签: haskell parsec

我为daily programmer redit challenge编写罗马数字解析器。我编写了一个parsec解析器来实现挑战的挑战部分。这是为了支持将其内容乘以1000的括号。

(II)II = 2002

现在我已经让解析器正常工作,但是使用try并不是很清楚。

这有效:

romAdv :: GenParser Char st RomAdv
romAdv = complex <|> simple

但这不是:

romAdv :: GenParser Char st RomAdv
romAdv = try simple <|> complex

任何人都可以解释一下吗?我认为它们有点等同。

代码:

data Numeral = I | V | X | L | C | D | M deriving (Read, Show)
type RomNum = [Numeral] deriving (Read, Show)
data RomAdv = Bracketed RomAdv RomNum | Simple RomNum deriving (Read, Show)

romNumbers :: GenParser Char st [RomAdv]
romNumbers = do
  numbers <- sepBy (romAdv) (char '\n')
  eof
  return numbers

romAdv :: GenParser Char st RomAdv
romAdv = complex <|> simple

complex :: GenParser Char st RomAdv
complex =
  do multed <- between (char '(') (char ')') romAdv
     remainder <- romNum
     return (Bracketed multed remainder)

simple :: GenParser Char st RomAdv
simple = do
  number <- romNum
  return (Simple number)

romNum :: GenParser Char st [Numeral]
romNum = many numeral

numeral :: GenParser Char st Numeral
numeral = do
  c <- char 'I' <|> char 'V' <|> char 'X' <|> char 'L' <|> char 'C' <|> char 'D' <|> char 'M'
  return $ read [c]

1 个答案:

答案 0 :(得分:3)

想出来。

因为这是我的语法会将""解析为(Simple [])。更改语法,以便Simple需要至少一个罗马数字,这给了我所需的行为。毕竟try工作得很好,表现得像我想的那样,我只是不认识它。

data Numeral = I | V | X | L | C | D | M deriving (Read, Show)
type RomNum = [Numeral]
data RomAdv = Bracketed RomAdv RomNum | Simple Numeral RomNum deriving (Show)

romAdv :: GenParser Char st RomAdv
romAdv = try simple <|> complex

simple :: GenParser Char st RomAdv
simple = do
  number1 <- numeral
  number <- romNum
  return (Simple number1 number)