【译】【未完成】Megaparsec 教程
关于 haskell 库 megaparsec 的中文资料凤毛麟角,其中比较系统的只有对 Megaparsec tutorial from IH book 的翻译 Megaparsec: Haskell 的语法分析组合子。无奈原教程对我这样的初学者来说水平过高,缺失细节,遇到错误也难以区分版本问题、环境问题或是自己的疏漏,故有了此注释版,希望也能帮到其他人。
注:原文提到这是一本未完成的书《Intermediate Haskell》中的一章,这本书已经夭折。
前置知识
大佬跳过,新手留步 看这里
最小化的 demo
MonadParsec
先看下 MonadParsec 定义
-- Text/Megaparsec.hs
class (Stream s, MonadPlus m) => MonadParsec e s m | m -> e s where
parseError :: ParseError s e -> m a
label :: String -> m a -> m a
hidden :: m a -> m a
hidden = label ""
try :: m a -> m a
lookAhead :: m a -> m a
notFollowedBy :: m a -> m ()
withRecovery :: (ParseError s e -> m a) -> m a -> m a
observing :: m a -> m (Either (ParseError s e) a)
eof :: m ()
token :: (Token s -> Maybe a) -> Set (ErrorItem (Token s)) -> m a
tokens :: (Tokens s -> Tokens s -> Bool) -> Tokens s -> m (Tokens s)
takeWhileP :: Maybe String -> (Token s -> Bool) -> m (Tokens s)
takeWhile1P :: Maybe String -> (Token s -> Bool) -> m (Tokens s)
takeP :: Maybe String -> Int -> m (Tokens s)
getParserState :: m (State s e)
updateParserState :: (State s e -> State s e) -> m ()
mkParsec :: (State s e -> Reply e s a) -> m a
Stream s
stream 是输入类型,不研究其细节了,使用 String, ByteString, Text, Lazy T 都可以。
MonadPlus m
MonadPlus 也是一个常见的类型类,用于处理两个同类型的 Monad,比如实现拼接、并发、选择等,其定义如下
MonadParsec e s m
MonadParsec 接收 3 个类型参数 e s m,其中 e 表示错误的类型,s 和 m 之前已经介绍过了。
m -> e s
这是一个 functional dependency 描述,含义是当 m 确定后,可以确定唯一的 e 和 s。
有了这个约束,Haskell 就可以更容易的推理 MonadParsec 的类型了。