我使用(滥用)解析器进行一些字符串转换,例如normalizeWS :: Parser String
删除重复的空格,normalizeCase
将特定字符串映射为小写。我使用解析器,因为输入数据有一些结构,例如有文化的字符串必须保持不变形。是否有一种优雅的方式将一个解析器的输出作为输入提供给下一个,从而形成转换管道? normalizeWS . normalizeCase
的某些东西(当然不起作用)?
非常感谢提前!
答案 0 :(得分:1)
我使用这种方法解决了问题...也许有更优雅的方式
preprocessor :: Parser String
preprocessor = normalizeCase `feeds` expandKettensatz `feeds` normalizeWs
feeds :: Parser String -> Parser String -> Parser String
feeds p1 p2 = do
s <- p1
setInput s
p2
答案 1 :(得分:0)
如果你有像
这样的功能normalizeWhitespace :: Stream s m Char => ParsecT s u m String
normalizeCase :: Stream s m Char => Set String -> Parsec s u m String
您可以使用runParser
和>>=
:
runBoth :: Stream s Identity Char => Set String -> SourceName -> s -> Either ParseError String
runBoth wordSet src input = do
input <- runParser normalizeWhitespace () src input
runParser (normalizeCase wordSet) () src input
但是这并没有为您提供一个可以与其他解析器链接在一起的解析器。
这并不奇怪,因为Parsec中的解析器组合就是全部 组成在同一个流上运行的解析器,而这些解析器依次运行 不同的流。
拥有多个不同的流也很常见 - 使用a tokenization or lexing pass as input to parsing的输出可以使过程更容易 理解,但Parsec is a little easier to use out of the box as a direct parser (without lexing/tokenization)。