【发布时间】:2017-05-26 10:33:46
【问题描述】:
在解析简单字符串的情况下,我遇到了 parsec 的奇怪行为
字符串示例是:
1 C1 1.1650 2.7470 -0.1840 ca 1 MOL 0.408200
2 N1 -0.0550 2.1750 -0.0380 nb 1 MOL -0.665000
3 C2 -0.2180 0.8450 0.1920 ca 1 MOL 0.450600
4 C3 -1.6310 0.3330 0.3310 c3 1 MOL -0.140700
我的解析器是
atom = do
str <- optional spaces *> (many1 $ (letter <|> digit <|> oneOf "-+.")) `sepBy` spaces
let id = read $ head str :: Int
let charge = (read.head.reverse) str :: Double
return (id,(str !! 1),charge)
records = atom `sepEndBy1` newline
我需要使用atom 解析器解析每个字符串。如果我只对一行使用原子解析器,它就可以工作。
但是如果尝试使用records 解析器,看起来第一个原子解析器会吃掉整个字符串。所以我有(1,C1,-0.140700) 而不是数组[(1,C1,-0.408200),(2,N1,0.665000)] 等。
附:在这种情况下,我根本无法理解 parsec 如何遍历带有 \n 符号的行。例如,如果我们有
onlyForTest = (many1 $ (letter <|> digit <|> oneOf "-+.")) `sepBy` spaces
并测试这样的例子:
*Main> parseTest onlyForTest "bla bl\na bla"
输出:
["bla","bl","a","bla"]
但是\n 符号不是sepBy 中的分隔符!
【问题讨论】:
-
我的问题是
spaces不仅接受空格字符,还接受制表符、换行符等。这就是atom接受所有字符串的原因。 -
是的,看起来是这样的
-
spaces由isSapace函数设计,它就是这样做的。