C++ 实现 Parsec
前一段时间看到了梨梨喵聚聚写的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的更多相关文章
- PARSEC安环境配置、运行
1.getting started 2.run PARSEC on simulators Full-System Simulators: such as Simics, GEM5.Trace-Driv ...
- Haskell语言学习笔记(57)Parsec(4)
Parser 类型 data ParsecT s u m a type Parsec s u = ParsecT s u Identity type Parser = Parsec String () ...
- Haskell语言学习笔记(46)Parsec(3)
Applicative Parsing 使用 Applicative 式的 Parser. 包括使用 (<$>), (<*>), (<$), (<*), (*> ...
- Haskell语言学习笔记(43)Parsec(2)
组合子 1 Prelude Text.Parsec Text.Parsec.String> parseTest (count 3 (char 'a')) "aaa" &quo ...
- Haskell语言学习笔记(41)Parsec(1)
Parsec Parsec是一个词法及语法分析器. 匹配字符与字符串 Prelude Text.Parsec> parseTest anyChar "a" 'a' Prelu ...
- PARSEC測试集的应用领域和working set的大小
參考:tp=&arnumber=4636090">PARSEC vs. SPLASH-2: A Quantitative Comparison of Two Multithre ...
- Real World Parsec --- 一个简便易学的 解释器
学习链接如下: http://bms.tratao.com/desktop/doc/0c3802e4ee404a71407f34996eff98ef 另外的解析器 ANTLR,学过一阵子,比较难,没应 ...
- 面向组合子设计Coder
面向组合子 面向组合子(Combanitor-Oriented),是最近帮我打开新世界大门的一种pattern.缘起haskell,又见monad与ParseC,终于ajoo前辈的几篇文章. 自去年9 ...
- PARSEC-3.0编译错误
OS: Ubuntu 14.04 LTS (x86_64) ***error 1 OpenSSL 1.0.1e 与 perl5.18 不兼容 POD document had syntax error ...
随机推荐
- 战争游戏(War Games 1983)剧情
战争游戏 War Games(1983) 人工控制导弹发射 傍晚大雾,两值工作人员自驾一辆轿车到达监控俄罗斯核战争的防空基地,在门口出示工作证后进入基地,两工作人员和同事换班后,进入防空系统控制室开始 ...
- xray 与 awvs 爬虫联动
awvs 的爬虫很好用,支持表单分析和单页应用的爬取,xray 的扫描能力比较强,速度也更快.awvs 和 xray 搭配使用则是如虎添翼.这里演示的是扫描 awvs 的在线靶站 http://tes ...
- Redis可视化内存分析工具--RDR:查看Redis中key的占用情况
RDR(redis datareveal)是一个解析redis rdbfile的工具.与redis-rdb-tools 相比,RDR 是由 golang 实现的,速度要快得多(5GB rdbfile ...
- Sentry 企业级数据安全解决方案 - Relay PII 和数据清理
本文档描述了一种我们希望最终对用户隐藏的配置格式.该页面仍然存在的唯一原因是当前 Relay 接受这种格式以替代常规数据清理设置. 以下文档探讨了 Relay 使用和执行的高级数据清理配置的语法和语义 ...
- win+ r 命令
Win 键+R calc:计算器 notepad:记事本 mspaint:画图 cmd:控制台 control:控制面板 desk.cpl:打开控制面板中的桌面设置 main.cpl:鼠标设置 ine ...
- 使用Cesium Stories来可视化时序数据
Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ Cesium可以用来可视化随时间变化的数据,无论是跨越数百年的地 ...
- 全网最全的Java SpringBoot点赞功能实现
前言 最近公司在做一个NFT商城的项目,大致就是一个只买卖数字产品的平台,项目中有个需求是用户可以给商品点赞,还需要获取商品的点赞总数,类似下图 起初感觉这功能很好实现,无非就是加个点赞表嘛,后来发现 ...
- golang中结构体的嵌套、方法的继承、方法的重写
package main import "fmt" type human struct { name, phone string age int8 } type student s ...
- MySQL基本数据类型之枚举与集合类型
目录 一:枚举 1.枚举 2.创建表(使用枚举) 3.表内添加数据 二:集合 1.集合 2.创建表(使用集合) 3.表内添加数据 一:枚举 1.枚举 枚举作用: 提前定义好数据之后 后续录入只能录定义 ...
- C++ 微信多开
应用是如何判断多开 一.通过查找窗口标题或者类名来判断程序是否正在运行. 二.通过互斥对象确定程序是否运行,大多数软件都是使用CreateMutexW 判断多开的. 三.内存映射物理文件,控制多开. ...