Parsec

Parsec是一个词法及语法分析器。

匹配字符与字符串

Prelude Text.Parsec> parseTest anyChar "a"
'a'
Prelude Text.Parsec> parseTest (char 'a') "a"
'a'
Prelude Text.Parsec> parseTest (satisfy (=='a')) "a"
'a'
Prelude Text.Parsec> parseTest (oneOf "abc") "a"
'a'
Prelude Text.Parsec> parseTest (string "a") "a"
"a"
  • anyChar 匹配任意字符
  • char c 匹配特定字符 c
  • satisfy p 匹配谓词 p
  • oneOf s 匹配字符串 s 中的任意字符
  • string s 匹配特定字符串 s

匹配0次,1次或多次

Prelude Text.Parsec> parseTest (many digit) "3"
"3"
Prelude Text.Parsec> parseTest (many digit) ""
""
Prelude Text.Parsec> parseTest (many1 digit) ""
parse error at (line 1, column 1):
unexpected end of input
expecting digit
Prelude Text.Parsec> parseTest (many1 digit) "3"
"3"
Prelude Text.Parsec> parseTest (many1 digit) "34"
"34"
Prelude Text.Parsec> parseTest (many digit) "34"
"34"
  • many 匹配0次1次或多次
  • many1 匹配1次或多次
  • digit 匹配数字

在 Parser Monad 中改变返回值类型

Prelude Text.Parsec Text.Parsec.String> num = do{ n <- many1 digit; return $ read n } :: Parser Integer
Prelude Text.Parsec Text.Parsec.String> parseTest num "123"
123

忽略空白

Prelude Text.Parsec Text.Parsec.String> whitespace = Control.Monad.void $ many $ oneOf " \n\t" :: Parser ()
Prelude Text.Parsec Text.Parsec.String> parseTest (whitespace >> anyChar) " a"
'a'
Prelude Text.Parsec Text.Parsec.String> lexeme = (\p -> whitespace >> p) :: Parser a -> Parser a
Prelude Text.Parsec Text.Parsec.String> parseTest (lexeme anyChar) " a"
'a'

sequence 和 choice

Prelude Text.Parsec Text.Parsec.String> parseTest (sequence [anyChar, anyChar]) "ab"
"ab"
Prelude Text.Parsec Text.Parsec.String> parseTest (anyChar >> anyChar) "ab"
'b'
Prelude Text.Parsec Text.Parsec.String> parseTest (choice [anyChar, digit]) "a"
'a'
Prelude Text.Parsec Text.Parsec.String> parseTest (choice [anyChar, digit]) "3"
'3'
Prelude Text.Parsec Text.Parsec.String> parseTest (anyChar <|> digit) "a"
'a'
Prelude Text.Parsec Text.Parsec.String> parseTest (anyChar <|> digit) "3"
'3'
  • sequence 匹配并且,与 (>>) 操作符有所不同。
  • choice 匹配或者,也可用 (<|>) 操作符

使用 try 来回溯

Prelude Text.Parsec Text.Parsec.String> parseTest (sequence [char 'a', char 'b'] <|> sequence [char 'a', char 'c']) "ac"
parse error at (line 1, column 2):
unexpected "c"
expecting "b"
Prelude Text.Parsec Text.Parsec.String> parseTest (try (sequence [char 'a', char 'b']) <|> sequence [char 'a', char 'c']) "ac"
"ac"
Prelude Text.Parsec Text.Parsec.String> parseTest (string "ab" <|> string "ac") "ac"
parse error at (line 1, column 1):
unexpected "c"
expecting "ab"
Prelude Text.Parsec Text.Parsec.String> parseTest (try (string "ab") <|> string "ac") "ac"
"ac"
  • 当 choice 的成员parser由多个parser组成时,该成员的某一部分parser成功某一部分parser失败将会导致该成员匹配失败,从而失去匹配其他成员parser的机会。
  • 此时应该使用 try 来强制回溯。

参考链接

Intro to Parsing with Parsec in Haskell

Haskell语言学习笔记(41)Parsec(1)的更多相关文章

  1. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  2. Haskell语言学习笔记(79)lambda演算

    lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...

  3. Haskell语言学习笔记(69)Yesod

    Yesod Yesod 是一个使用 Haskell 语言的 Web 框架. 安装 Yesod 首先更新 Haskell Platform 到最新版 (Yesod 依赖的库非常多,版本不一致的话很容易安 ...

  4. Haskell语言学习笔记(20)IORef, STRef

    IORef 一个在IO monad中使用变量的类型. 函数 参数 功能 newIORef 值 新建带初值的引用 readIORef 引用 读取引用的值 writeIORef 引用和值 设置引用的值 m ...

  5. Haskell语言学习笔记(39)Category

    Category class Category cat where id :: cat a a (.) :: cat b c -> cat a b -> cat a c instance ...

  6. Haskell语言学习笔记(43)Parsec(2)

    组合子 1 Prelude Text.Parsec Text.Parsec.String> parseTest (count 3 (char 'a')) "aaa" &quo ...

  7. Haskell语言学习笔记(57)Parsec(4)

    Parser 类型 data ParsecT s u m a type Parsec s u = ParsecT s u Identity type Parser = Parsec String () ...

  8. Haskell语言学习笔记(46)Parsec(3)

    Applicative Parsing 使用 Applicative 式的 Parser. 包括使用 (<$>), (<*>), (<$), (<*), (*> ...

  9. Haskell语言学习笔记(72)Free Monad

    安装 free 包 $ cabal install free Installed free-5.0.2 Free Monad data Free f a = Pure a | Free (f (Fre ...

随机推荐

  1. Arrays、ArrayUtils 区别

    Arrays java.util 包提供的静态类:java.util.Arrays 此静态类专门用来操作array ,提供搜索.排序.复制等静态方法. ArrayUtils apache 提供的类:o ...

  2. POJ3468——树状数组支持两个区间操作

    题目:http://poj.org/problem?id=3468 推断过程可自己查,得式子:fixsum(x) = (x+1) * ∑(i=1,x)fi - ∑(i=1,x)i*fi; 其中 f 是 ...

  3. Ionic 3 自定义组件的使用

    1. 创建组件 ionic g component myComponent myComponent为组件名称 创建好后,生成的文件如下图 2. 在Page 中使用 使用的是home 在home.htm ...

  4. x86 openwrt虚拟路由代理上网

    一.代理服务器设置 1.下载代理软件CCProxy 6.8 Build 2.设置如下 二.x86 路由设置 1.在/etc目录下编辑profile http_proxy= https_proxy= f ...

  5. bzoj1830 Y形项链

    Description 小可可得到了一个可爱的Y型项链.小可可现在的项链是这个样子的:项链的最中间有一颗大珍珠作为结合点,从大珍珠上连出来3条由各种宝石串起来的链子.小可可希望让这3个链子完全一样,她 ...

  6. 第14章 UDP编程(2)_端口绑定和域名解析

    2. 端口绑定和域名解析 2.1 端口绑定:SO_REUSEADDR选项 ;//1表示启用该选项 //设置为可重新使用端口,每次启动该端口时,会重新绑定端口.相当于端口被复位并被重新. //绑定.因此 ...

  7. 第12章 网络基础(1)_网络分层和TCP/IP协议族

    1. 协议的概念 (1)计算机网络中实现通信必须有一些约定.如对速率.传输代码.代码结构.传输控制步骤和出错控制等约定,这些约定即被称为通信协议 (2)在两个节点之间要成功地进行通信,两个节点之间必须 ...

  8. 解决Mac nginx问题 [emerg] 54933#0: bind() to 0.0.0.0:80 failed (13: Permission denied)

    brew services restart nginx Stopping nginx... (might take a while) ==> Successfully stopped nginx ...

  9. Hive环境的安装部署(完美安装)(集群内或集群外都适用)(含卸载自带mysql安装指定版本)

    Hive环境的安装部署(完美安装)(集群内或集群外都适用)(含卸载自带mysql安装指定版本) Hive 安装依赖 Hadoop 的集群,它是运行在 Hadoop 的基础上. 所以在安装 Hive 之 ...

  10. ECCV 2018 | UBC&腾讯AI Lab提出首个模块化GAN架构,搞定任意图像PS组合

    通常的图像转换模型(如 StarGAN.CycleGAN.IcGAN)无法实现同时训练,不同的转换配对也不能组合.在本文中,英属哥伦比亚大学(UBC)与腾讯 AI Lab 共同提出了一种新型的模块化多 ...