前一段时间看到了梨梨喵聚聚写的Parser Combinator 在 C++ 里的 DSL, 感觉好厉害, 正好毕设里要写一部分前端, 昨天又把这篇文章看了一遍, 想着我也要用这么酷炫的东西来参与一下毕设, 于是今天仿了一个, 不过由于电脑屏幕太小(理由), 看不懂梨梨喵聚聚的代码, 只好照着文章里的理念自己试着实现一下, 类的设计应该差不多, 不过具体的实现应该鶸了很多, 代码在parsec, 目前还不支持左递归和垃圾回收(

先上一个加减的小例子吧:

Parsec<char> Decimal;
Parsec<string> Number;
Parsec<int> Primary, Additive, Additive_; // Decimal := '0' | ... | '9'
Decimal = ('0'_T | '1'_T | '2'_T | '3'_T | '4'_T | '5'_T | '6'_T | '7'_T | '8'_T | '9'_T ); // Number := Decimal Number | Decimal
Number =
(Decimal + Number >>
[](char decimal, string number) {
return decimal + number;
}) |
(Decimal >>
[](char decimal) {
return string() + decimal;
}); // Primary := Number
Primary = Number >> [](string number) {
return stoi(number);
}; // Additive := Primary Additive_ | Primary
// Additive_ := + Additive | - Additive
Additive =
(Primary + Additive_ >>
[](int primary, int additive) {
return primary + additive;
}) |
(Primary >> [](int primary) {
return primary;
});
Additive_ = (('+'_T | '-'_T) + Additive >> [](char op, int additive) {
return (op == '+' ? additive : -additive);
}); cout << Additive("1+2+3") << endl;

例子是改的梨梨瞄聚聚的, 因为不支持左递归, 只能手动提取公因子了(

和梨梨瞄聚聚重复的原理部分就不说了, 想知道的可以看一下梨梨瞄聚聚的那篇文章, 说一下不一样的地方吧, 我的实现里的类型笛卡尔乘积的结果使用 std::tuple<Ts...> 表示的, 类型的和的结果用 std::variant<Ts...> 表示, 当返回值的类型可能有多类型的时候就可以使形参的类型为 std::variant<Ts...>, 保证类型安全的同时还能接收多个类型的结果, 同样可以令组合子返回的是一个 tuple 类型, 可以继续和其它类型相乘或者相加, 后边就可以简化实现.

写了好几个小时, 虽然代码不多, 但是模板多起来密度太大真的眼花缭乱, 希望之后能支持一下左递归之类的操作吧, 毕竟还要拿来写毕设, 边用边改吧(

C++ 实现 Parsec的更多相关文章

  1. PARSEC安环境配置、运行

    1.getting started 2.run PARSEC on simulators Full-System Simulators: such as Simics, GEM5.Trace-Driv ...

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

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

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

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

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

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

  5. Haskell语言学习笔记(41)Parsec(1)

    Parsec Parsec是一个词法及语法分析器. 匹配字符与字符串 Prelude Text.Parsec> parseTest anyChar "a" 'a' Prelu ...

  6. PARSEC測试集的应用领域和working set的大小

    參考:tp=&arnumber=4636090">PARSEC vs. SPLASH-2: A Quantitative Comparison of Two Multithre ...

  7. Real World Parsec --- 一个简便易学的 解释器

    学习链接如下: http://bms.tratao.com/desktop/doc/0c3802e4ee404a71407f34996eff98ef 另外的解析器 ANTLR,学过一阵子,比较难,没应 ...

  8. 面向组合子设计Coder

    面向组合子 面向组合子(Combanitor-Oriented),是最近帮我打开新世界大门的一种pattern.缘起haskell,又见monad与ParseC,终于ajoo前辈的几篇文章. 自去年9 ...

  9. PARSEC-3.0编译错误

    OS: Ubuntu 14.04 LTS (x86_64) ***error 1 OpenSSL 1.0.1e 与 perl5.18 不兼容 POD document had syntax error ...

随机推荐

  1. 基于CentOS7.x gitlab环境搭建,卸载,汉化 --汉化篇

    gitlab环境搭建,卸载,汉化--汉化篇 注意gitlab的版本需和汉化版本一致 安装git yum install -y git 下载最新的汉化包 cd git clone https://git ...

  2. js 将数字型 的字符串 转 数字 【整数 /浮点型数字】

    1. js 提供了两种可以将 数字型 的字符串 转 数字 的方法 parseInt()和parseFloat(), parseInt() 是转成整数, 但 向下去整数 , parseFloat() 是 ...

  3. centos7 系统正则符号

    点符号 . 匹配任意一个字符,且只有一个字符 星符号 * 匹配任意0和或多个以上连续的字符 扩展符号 括号符号[] 匹配括号出现的字符信息 [^abc] --表示排除含有abc字符的内容,是单个字符a ...

  4. unittest测试框架

    unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果. 一.u ...

  5. Flowable实战(八)BPMN2.0 任务

      任务是流程中最重要的组成部分.Flowable提供了多种任务类型,以满足实际需求.   常用任务类型有: 用户任务 Java Service任务 脚本任务 业务规则任务 执行监听器 任务监听器 多 ...

  6. 《剑指offer》面试题19. 正则表达式匹配

    问题描述 请实现一个函数用来匹配包含'. '和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次).在本题中,匹配是指字符串的所有字符匹配整个模式. ...

  7. Golang 基准测试Benchmark

    基准测试 Go语言标准库内置的 testing 测试框架提供了基准测试(benchmark)的能力,实现了对某个特定目标场景的某项性能指标进行定量的和可对比的测试. 基本规则 基准测试的代码文件必须以 ...

  8. 问题记录——BigDecimal保留两位小数及格式化成百分比

    1.函数总结 BigDecimal.setScale()方法用于格式化小数点 setScale(1)表示保留一位小数,默认用四舍五入方式 setScale(1,BigDecimal.ROUND_DOW ...

  9. 简述ASP.NET网站开发步骤

    新建解决方案 清除解决方案 重新生成解决方案 发布应用程序 设置配置文件 重命名配置文件 发布后生成的文件 IIS安装 安装完成后,输入http://localhost/出现 打开IIS 添加自己的网 ...

  10. 基于 NFS 搭建便捷远程硬盘

    基于 NFS 搭建便捷远程硬盘 知识准备: 一.NFS服务简介 NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向 ...