Created
February 19, 2024 06:28
-
-
Save tangentstorm/054de51c34eae8739528ccfca4906006 to your computer and use it in GitHub Desktop.
javascript parser combinators ( https://youtube.com/live/ZfjORjtkDpI )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let set=(o,k,v)=>{let r={...o}; r[k]=v; return r} | |
let gs=k=>(x,y)=> y===undefined ? x[k] : set(y,k,x) | |
let mb=gs('mb'), // match bit | |
ib=gs('ib'), // input buffer | |
ix=gs('ix'), // index into input buffer | |
ch=gs('ch'), // current character (ib[ix]) | |
mk=gs('mk'); // start index of current token | |
let s0=()=>({mb:0,ib:'',ch:'',ix:-1,mk:-1}) | |
on=s=>ix(0,ch(s[0],ib(s,s0()))) | |
m1=s=>mb(1,s) // match | |
m0=s=>mb(0,s) // fail | |
let nx=s=>{let i=1+ix(s),b=ib(s); return ch(b[i], ix(i, s))} | |
fw=(n,s)=>{for(let i=0;i<n;i++)s=nx(s); return s} | |
emp=m1 // always matches, consumes nothing | |
fwm=(n,s)=>mb(+n, fw(+n,s)) | |
any=s=>fwm(ix(s)<ib(s).length, s) | |
neg=p=>s=>mb(1-mb(p(s)),s) | |
end=neg(any) | |
chr=c=>s=>fwm(c==ib(s)[ix(s)],s) | |
chs=cs=>s=>fwm(cs.includes(ib(s)[ix(s)]),s) | |
seq=ps=>s=>{let r=s;for(p of ps){r=p(r);if(!mb(r))return m0(s)}return r} | |
alt=ps=>s=>{for(p of ps){let r=p(s);if(mb(r))return r} return m0(s)} | |
opt=p=>alt([p,emp]) | |
lit=cs=>seq([...cs].map(chr)) | |
rep=p=>s=>{let r=m1(s);while(mb(r)){r=p(r)}return mb(+(ix(s)<ix(r)),r)} | |
orp=p=>alt([rep(p), emp]) | |
not=p=>seq([neg(p),any]) | |
sep=(p,d)=>seq([p, orp(seq([d, p]))]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment