Parsec - 由主要内容子集分隔的输入

时间:2014-06-14 15:02:13

标签: haskell irc parsec

作为一种练习项目,我想实现一个解析IRC消息的库。我需要解析的一件事是短名,由BNF给出:

shortname = ( letter / digit ) *( letter / digit / "-" ) *( letter / digit )

我有解析器alphaNum(alphaNum <|> char '-'),对应于这些元素,这很容易。但是,我很难将它们组合起来以符合规范。 between alphaNum alphaNum (alphaNum <|> char '-')无效,我无法将lookAhead纳入其中,使其按照我的意愿行事。

1 个答案:

答案 0 :(得分:2)

问题是前一部分消耗了最后一部分(字母或数字,但不是破折号)。我建议将语法改为

  

短名=(字母/数字)*(*(“ - ”)(字母/数字))

或者更高效

  

shortname = +(字母/数字)*(+(“ - ”)+(字母/数字))

这确保了虽然内部部分可以包含字母,数字和短划线,但任何短划线必须始终后跟字母/数字。一个parsec解决方案可能是

shortName :: Stream s m Char => ParsecT s u m String
shortName = (++) <$> many1 alphaNum
                 <*> (concat <$> many ((++) <$> many1 (char '-')
                                            <*> many1 alphaNum))