MCH*_*MCH 5 parsing haskell runtime-error parsec
import Text.ParserCombinators.Parsec
delimiter :: Parser ()
delimiter = do char '|'
return ()
<?> "delimiter"
eol :: Parser ()
eol = do oneOf "\n\r"
return ()
<?> "end of line"
item :: Parser String
item = do entry <- manyTill anyChar (try eol <|> try delimiter <|> eof)
return entry
items :: Parser [String]
items = do result <- many item
return result
Run Code Online (Sandbox Code Playgroud)
当我运行parseTest items "a|b|c"上面的代码时,我收到以下错误:
*** Exception: Text.ParserCombinators.Parsec.Prim.many:
combinator 'many' is applied to a parser that accepts an empty string.
Run Code Online (Sandbox Code Playgroud)
我相信这是与eof和many item,如果我删除eof,然后我可以得到,只要它的工作作为行不结束eof,这使得它那种无用的.
我意识到我可以使用,sepBy但我感兴趣的是为什么这个代码不起作用以及如何使它工作.
像这样的解析器many确实不能应用于接受空字符串的解析器,因为这会使语法不明确:你解析空字符串的频率是多少?选择不同的数字可能导致不同的解析结果......
你认为这many item是有问题的组合是正确的.An item是用来定义的manyTill.(游览:顺便说一下,你可以简化manyTill到
item :: Parser String
item = manyTill anyChar (eol <|> delimiter <|> eof)
Run Code Online (Sandbox Code Playgroud)
不需要do或者return,也不需要try,因为三个解析器中的每一个都期望不同的第一个令牌.)解析器manyTill因此解析任意数量的字符,然后是a eol,a delimiter或an eof.现在,eol和delimiter实际消耗至少一个字符,当他们成功,但eof没有.解析器eof在输入结束时成功,但可以多次应用.例如,
ghci> parseTest (do { eof; eof }) ""
()
Run Code Online (Sandbox Code Playgroud)
它不消耗任何输入,因此可以item在空字符串上(在输入结束时)成功,从而导致模糊.
要解决这个问题,你确实可以重写你的语法并转移到类似的东西sepBy,或者你可以尝试区分正常的items(eof不允许作为结束标记)和final item(eof允许的地方).
| 归档时间: |
|
| 查看次数: |
1479 次 |
| 最近记录: |