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语言学习笔记(30)MonadCont, Cont, ContT

    MonadCont 类型类 class Monad m => MonadCont m wherecallCC :: ((a -> m b) -> m a) -> m a ins ...

  2. Haskell语言学习笔记(73)Existentials

    Existentials(存在类型) Existentially quantified types(Existentially types,Existentials)是一种将一组类型归为一个类型的方式 ...

  3. C语言如何加缓冲,C语言学习笔记之输出缓冲

    在c语言中经常用到输出函数printf,当我们像往常一样在输出函数中输入我们的想要的输出的东西后加\n换行 验证结果如我们输出的一样 如果我们在后面加入死循环会不会出现这些语句呢 结果卡死了,可还是输 ...

  4. 【Go语言 · 学习笔记】

    文章目录 Go语言 · 学习笔记 一.Go包管理 1. 什么是Go语言中的包 2. 包的命名 3. main包 4. 导入包 5. 远程包导入 6. 命名导入 7. 包的init函数 二.Go开发工具 ...

  5. Lawliet|C语言学习笔记5——循环结构

    C语言学习笔记--循环结构 1.求1+2+3+-+100 #include<stdio.h> int main() {int i=1,sum=0; //定义变量i的初值为1,sum的初值为 ...

  6. 梓益C语言学习笔记之链表&动态内存&文件

    梓益C语言学习笔记之链表&动态内存&文件 一.定义: 链表是一种物理存储上非连续,通过指针链接次序,实现的一种线性存储结构. 二.特点: 链表由一系列节点(链表中每一个元素称为节点)组 ...

  7. 6.方法(go语言学习笔记)

    6.方法(go语言学习笔记) 目录 定义 匿名字段 方法集 表达式 1. 定义 方法是与对象实例绑定的特殊函数. 方法是面向对象编程的基本概念,用于维护和展示对象的自身状态.对象是内敛的,每个实例对象 ...

  8. 梓益C语言学习笔记之指针

    梓益C语言学习笔记之指针 一.32位平台下,地址是32位,所以指针变量占32位,共4个字节 二.内存单元的地址即为指针,存放指针的变量称为指针变量,故:"指针"是指地址,是常量,& ...

  9. c语言中void arrout,c语言学习笔记(数组、函数

    <c语言学习笔记(数组.函数>由会员分享,可在线阅读,更多相关<c语言学习笔记(数组.函数(53页珍藏版)>请在人人文库网上搜索. 1.数组2010-3-29 22:40一维数 ...

最新文章

  1. 人眼是具有插帧能力的
  2. 安装完CentOS可以不做的事
  3. 使用阿里巴巴json映射_使用JSON模式验证来映射稀疏JSON
  4. 《隐秘的角落》数学学霸朱朝阳如何炼成?这3招,你家孩子也能用上!
  5. JavaScript提升(Hoisting)---借鉴自W3CSchool
  6. 深入理解JVM--类的执行机制
  7. Python基于 ImageAI 模块实践 idenprof数据集识别预测分析
  8. CentOS 6.5 shell中su切换自动输入密码
  9. mysql 多主一从备份_Linux下安装Mysql多实例作为数据备份服务器实现多主到一从多实例的备份 | 很文博客...
  10. 收藏 | 数据资源下载网址大全
  11. windows下安装redis并设置自启动
  12. B站手机APP缓存视频(m4s)转换为mp4格式
  13. 这款台灯,不仅能护眼,还能点读和互动
  14. 上交大计算机在职研究生学费,交大在职研究生学费
  15. java推算日期后天_分别用C++和Java写的计算后天的日期code
  16. Python、Java、Scala、Go Package对照表
  17. Linux 内核模块符号信息以及strip命令
  18. 【PSO三维路径规划】粒子群算法融合鸡群算法多无人机三维路径规划【含Matlab源码 1792期】
  19. Elasticsearch 快照生命周期管理 (SLM) 实战指南
  20. ubuntu启动时的初始化信息一

热门文章

  1. CSS的浮动以及清楚浮动的方法
  2. GetKeyState和GetAsyncKeyState的区别
  3. Chrome开发自定义右键菜单实现快速跳转到指定页面
  4. Anaconda下载以及创建自己的环境
  5. SVN拉取和Excel冲突合并
  6. 「转行程序员」30岁想转行还能做什么?月入两万职位大比拼
  7. visualSVN server的安装和使用
  8. 高效短眠的10个好处及如何进行高效的睡眠
  9. 西门子PCS7系统NTP网络时钟同步(NTP时钟发生器)介绍
  10. C# 后台 背景图片拼接图片与文字,文字图片生成与背景图片合成