Parsec遇到线路问题

时间:2012-05-24 18:43:21

标签: haskell parsec

我有一个Parsec解析器,我写的主要是应用风格。在一种情况下(我唯一一次使用sepBy)我遇到了eol解析器的问题。首先,一些定义:

eol =   try (string "\n\r")
    <|> try (string "\r\n")
    <|> string "\n"
    <|> string "\r"
    <?> "eol"

betaLine = string "BETA " *> (StrandPair <$> p_int <*> p_int <*> p_int <*> (p_int *> p_direction) <*> p_exposure) <* eol

注意:betaLine效果很好(为简洁起见,我省略了p_int的定义,等等:

*HmmPlus> parse betaLine "beta" "BETA 6 11 5 24 -1 oiiio\n"
Right (StrandPair {firstStart = 6, secondStart = 11, pairLength = 5, parallel =   Antiparallel, exposure = [Exposed,Buried,Buried,Buried,Exposed]})

另一个解析器hmmMatchEmissions

会出现问题
 hmmMatchEmissions     = spaces *> (V.fromList <$> sepBy p_logProb spaces) <* eol <?> "matchEmissions"

*HmmPlus> parse hmmMatchEmissions "me" "      2.61196  4.43481  2.86148  2.75135  3.26990  2.87580  3.69681\n"
Left "me" (line 2, column 1):
unexpected end of input

现在,如果我从解析器定义中删除<* eol,并从行中删除\n,它确实有效:

*HmmPlus> parse hmmMatchEmissions "me" "      2.61196  4.43481  2.86148  2.75135  3.26990  2.87580  3.69681"
Right (fromList [NonZero 2.61196,NonZero 4.43481,NonZero 2.86148,NonZero 2.75135,NonZero 3.2699,NonZero 2.8758,NonZero 3.69681])

那么,为什么eol适用于betaLine但不适用hmmMatchEmissions

我会注意到这是我唯一使用sepBy的地方;这可能是一个线索吗?

更新:我已经完成了以下操作,现在失败了:/

reqSpaces = many1 (oneOf " \t")

optSpaces = many (oneOf " \t")

hmmMatchEmissions = optSpaces *> (V.fromList <$> sepBy1 p_logProb reqSpaces) <* eol <?> "matchEmissions"

这就是失败:

*HmmPlus> parse hmmMatchEmissions "me" "  0.123  0.124\n"
Left "me" (line 1, column 10):
unexpected "0"
expecting eol

我会注意到第10列中的意外00.124令牌的第一个字符。

1 个答案:

答案 0 :(得分:4)

问题似乎是你的p_logProb解析器消耗了空白。所以,这就是解析期间发生的事情:

  0.123  0.124\n
[]               optSpaces
  [-----]        p_logProb
         {       trying reqSpaces
         {       trying eol
                 failure: expecting eol

p_logProb解析器应该只使用它解析的东西,即实际的数字。这将导致预期的解析:

  0.123  0.124\n
[]               optSpaces
  [---]          p_logProb
       []        reqSpaces
         [---]   p_logProb
              {  trying reqSpaces
              #  eol