我想为一种允许文件包含的简单语言实现一个Parsec解析器。 即,语言看起来像这样:
include otherfile;
expression in the language;
如果解析了包含,我想读取具有此名称的文件并将其解析的内容嵌入到父结构中。
由于我必须读取文件,因此解析器需要打包在IO中。我的猜测是,ParsecT s u m a
中的底层单子u
可用于此目的。然而,这导致了语言定义的一些变化,因为LanguageDef依赖于Identity
作为底层monad。
我的方法合理吗?是否有其他方法可以在解析器中包含文件,例如,扩展输入流?
好的,这是我想出的:
parsecTrans :: Monad m => ParsecT s u Identity a -> ParsecT s u m a
parsecTrans p = mkPT $ s -> return $ fmap (return . runIdentity) $ runIdentity $ (runParsecT p) s
此函数解压缩ParsecT
monad 并将其推广为任意 monad。您可以使用它将所有基于 Identity
的解析器提升为基于 IO
的解析器。