/tmp/duangsuse.sock
我发现这个 ws0P 实现的果然还是不仅仅不对,而且还不能忽视它的不对...
它在有且只有一个空格的时候,直接把下一项目跳过了 然后继续扫描空格...
/tmp/duangsuse.sock
我发现这个 ws0P 实现的果然还是不仅仅不对,而且还不能忽视它的不对...
你说我这是设计个啥劲.... 放着好的 next 不用,反而舍近求远去用 duplast.... 根本没有组合的概念
/tmp/duangsuse.sock
那么要实现这么一个了不起的语法(迫真,不过其实你实现了这个之后,类似 JSON、TOML 这样的语法的解析器也不难做了,YAML 这种你需要加一个手写子解析器) 首先咱得做好理论准备,是吧? 所以感兴趣的朋友请耐心地接着看,你马上就要自创一门配置文件语法了呢~ 而且,这个语言的代码还可以在 JavaScript 里被求值为标准的 object,是不是很 Happy 呢~ 要解析 [1, 2, 3] 这种列表,我们就得先重视 FP.js parserc 的一个缺陷 -- seq/manyFold/someFold…
最终的解决方案呢?
不过得同步我最新的修复版本 FP.js...
const p = require('./fp').parserc;
let __ = p.wsP(), _ = p.ws0P();
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[2]);
let List_ItemsP = p.manyFold(pa, [[], (v,x)=>v.concat(x)]);
let ListP = p.seq([ p.charP('['), _, p.possible([ p.charP(']'), p.skip(']'), p.seq([numP, _, List_ItemsP, p.charP(']')]) ]) ]);
pp = p.run(ListP); 不过得同步我最新的修复版本 FP.js...
/tmp/duangsuse.sock
最终的解决方案呢? const p = require('./fp').parserc; let __ = p.wsP(), _ = p.ws0P(); 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[2]);…
... 我受不了目前这个辣鸡反向思维架构了,重构算了
为什么 seq 要多管闲事,不消耗字符还得手动弄个 keepLast,还能够多次 keepLast... 只是因为支持内嵌在 seq 里面, 我...
为什么 seq 要多管闲事,不消耗字符还得手动弄个 keepLast,还能够多次 keepLast... 只是因为支持内嵌在 seq 里面, 我...
从此 FP.js 的解析组合子无需再考虑『哥哥』是一个有强迫症的哥哥还是一个正常的哥哥了。
尤其是在组合的时候,绝对不需要了、不再需要了
不会再有莫名其妙多跳一两个字符的问题了,子解析器解析的了就跳、解析不了就不跳。解析不了 seq 直接失败、possible 尝试下一个解析器。
再也不会 seq 里嵌套 seq/many,还需要 duplast N (视嵌套情况而定,呵呵)次呦....
尤其是在组合的时候,绝对不需要了、不再需要了
不会再有莫名其妙多跳一两个字符的问题了,子解析器解析的了就跳、解析不了就不跳。解析不了 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)
/tmp/duangsuse.sock
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}…
🤔 JavaScript 不能 copy... 好麻烦哦,我只好弄个函数 来帮忙造新 Array... 毕竟不能一直用一个实例去折叠...
/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')…
有了这些语法定义和之前对
用啥 XML 呢???万能的 XML。
幸运的是,这意味着你已经可以编写 GeekSpec 这样的 DSL 了!(记得 GeekSpec 可是把之前需要两天的『劳动密集』繁复任务量,缩减到了两个小时!)可能过一段时间我会再写更多的,甚至实现一个 ES5 (JavaScript)的解析器... 之前本频道也有教写计算器(动态二元运算符优先级解析程序)什么的
下面我只发实现,如果你还不知道怎么做,请复习一下刚才的内容,动手实践一下
如果还不知道的话,大概是需要时间理解了。
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)的解析器... 之前本频道也有教写计算器(动态二元运算符优先级解析程序)什么的
下面我只发实现,如果你还不知道怎么做,请复习一下刚才的内容,动手实践一下
如果还不知道的话,大概是需要时间理解了。
酷 壳 - CoolShell
信XML,得自信 | | 酷 壳 - CoolShell
XML可能是计算有史以来最NB的发明了,以至于我们以没有XML的程序是难登大堂的程序,不用XML,你都不好意思当程序员。于是,我们看到了很多很雷人的用法(《信XML,得永生》),当然一些朋友当时并没有看懂,不过我不怪大家,因为我们依然深信使用XML可以让你有强大的Zhuangbility,于是我们有下面这两种相当Geiliable的用法。 一、XML中的XML 这个例子是某公司的一个SOAP实现—