/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... 毕竟不能一直用一个实例去折叠...