/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
现在所有哥哥就是哥哥、弟弟就是弟弟,哥哥不再强迫弟弟 next 了
『当一个称职的哥哥、不再区分 possible 和 seq/some/many』
组合 不分家
从此 FP.js 的解析组合子无需再考虑『哥哥』是一个有强迫症的哥哥还是一个正常的哥哥了。
尤其是在组合的时候,绝对不需要了、不再需要了
不会再有莫名其妙多跳一两个字符的问题了,子解析器解析的了就跳、解析不了就不跳。解析不了 seq 直接失败、possible 尝试下一个解析器。
再也不会 seq 里嵌套 seq/many,还需要 duplast N (视嵌套情况而定,呵呵)次呦....
『以为是各种问题很奇怪,其实是因为思路不清晰,把简单的问题弄复杂了』
辣鸡架构,拜拜喽!
const p = require('./fp').parserc;
let __ = p.wsP(), _ = p.ws0P();

function NumList(l, ws0, rxs) {
this.wss = []; this.ary = [];
this.wss.push(ws0); // {ws0} x...
if (rxs === ']') { return; }
this.ary.push(rxs[0]); this.wss.push(rxs[1]); // x {a}, y, ..
for (let [wl, x, wr] of rxs[2]) { this.ary.push(x); this.wss.push(wl, wr); }
}
let numP = p.someFold(p.elemP('0123456789'.split(''), 'digit'), [0, (a,x) => a*10+(x-'0')], f => 'number value expected');
let pa = p.seq([p.charP(','), _, numP, _], xs => [xs[1], xs[2], xs[3]]);
let List_ItemsP = p.manyFold(pa, [p.makeNew(Array), (v,xs)=>{v.push(xs); return v;}]);
let ListP = p.seq([ p.charP('['), _, p.possible([ p.charP(']'), p.seq([numP, _, List_ItemsP, p.charP(']')]) ]) ], p.makeNew(NumList));
pp = p.run(ListP);


尾逗号的问题是正常情况,因为这个毕竟是 manyFold, 解析到不能匹配了就 fail... 第一个 charP 还是可以解析那个尾逗号的
如果需要不支持尾逗号的话,还需语法变形才行...(当然你也可以设置 pa 的 msgr 为直接 throw error 的那种,所有组合基本都只会 handle pfail,不会 handle msgr 抛出的 exception)
『就说呢,一定是可以做到的!』 这样就有了第一门自己的 markup language!
怎么样~ 成功了吗?
This media is not supported in your browser
VIEW IN TELEGRAM
接下来,一起实现这门新的 『DEF』 DSL (领域专属语言)语言吧! #Parser #PLT

使用 FP.js 的解析组合子功能,就可以快速制造各种拥有良好用户界面和错误处理的的 DSL!

就像之前写 GeekSpec 的时候说的:

面向语言编程,是个不错的逻辑。如果你觉得要处理的问题使用某门语言的文法十分鸡肋冗长繁复难看,为什么不创建一门专门的语言来清晰地描述它呢?
在完成这门 『DEF』 DSL 只后,你还可以写更多更好、甚至写的更像一种通用编程语言的 DSL

并且,以后的编程路上,拥有这类 DSL 的能力会让你写出更优质的程序、提升你编程的速度,避免模板代码的编写、完成更有特色的程序...
/tmp/duangsuse.sock
那咱来看一下这个 继续 🐱 我们刚才说道了第一个组合解析器 — seq 函数,现在测试一下 首先,你需要同步 FP.js 库的版本,以引入新的一些抽象操作 const p = require('./fp').parserc; function DefItem(_d, w0, name, w1, _eq, w2, val) { this.wss = [w0, w1, w2]; this.name = name; this.value = val; } ps = p.seq([p.kwP('def')…
有了这些语法定义和之前对 def abc = 123 \ [1,2,3,4] 的解析程序,我们现在已经可以实现这样的语法了:

TheDefLang = {{ Def }}
Def = (<def> Name <=> Value NL) | (<lets> Name Name) | (<just> Name)
NL = '\n'|'\r'
Letter = ('a'~'z'|'A'~'Z'|'_')
Digit = ('0'~'9')
Name = Letter (Letter|Digit)*
Value = Bool | Num | Str | Name | Array | Map

Bool = <true> | <false>
Num = Digit+
Str = <"> char* <">
Array = <[> (<]> | Value { <,> Value } <]>)
KVPair = Name <:> Value
Map = <{> (<}> | { KVPair { <;> KVPair } <}>)

Def 语言是一门简单的数据描述语言,你可以定义(全局)变量、引用变量、赋值变量、返回变量。
用啥 XML 呢???万能的 XML。

幸运的是,这意味着你已经可以编写 GeekSpec 这样的 DSL 了!(记得 GeekSpec 可是把之前需要两天的『劳动密集』繁复任务量,缩减到了两个小时!)可能过一段时间我会再写更多的,甚至实现一个 ES5 (JavaScript)的解析器... 之前本频道也有教写计算器(动态二元运算符优先级解析程序)什么的

下面我只发实现,如果你还不知道怎么做,请复习一下刚才的内容,动手实践一下
如果还不知道的话,大概是需要时间理解了。
利用惰性导出和代理,来实现递归(没 Y 组合子的好,迫真,虽然 Y 组合子是递归自己...)
第一个完全自己写的数据描述语言? 🤔
编写的直播到此就 告一段落了,接下来是一些语言工具设计的考虑。
真香
很好的功能,国内呵呵。
就凭国内大部分程序员的水平,和小部分真·大佬的速度和创意,想\做不到这种东西
至少在信号处理和语音合成层面,国外比国内强很多