Skip to content

Instantly share code, notes, and snippets.

@shamansir
Last active March 13, 2020 21:38
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shamansir/40eaffb802beaefd9443 to your computer and use it in GitHub Desktop.
Save shamansir/40eaffb802beaefd9443 to your computer and use it in GitHub Desktop.
peg.js-fn operators
// syntax: .
// example: start = . . .
function ch() {
if (pos >= ilen) failed(ANY, EOI);
return input[pos++];
}
// syntax: "<string>", '<string>'
// example: start = . 'oo'
function match(str) {
var slen = str.length;
if ((pos + slen) > ilen) { failed(str, EOI); }
if (input.substr(pos, slen) === str) {
pos += slen; return str;
}
failed(str, cc());
}
// syntax: [<symbols>], [^<symbols>], [<symbol_1>-<symbol_n>], [^<symbol_1>-<symbol_n>], "<string>"i, '<string>'i
// example: start = [^f-o]+
function re(rx, desc) {
var res, desc = desc || rx.source;
if (res = rx.exec(input.substr(pos))) {
if (res.index !== 0) failed(desc, cc());
pos += res[0].length; return res[0];
} else failed(desc, cc());
}
// syntax: $<expression>
// example: start = $(. . .)
function text(f) {
var p_pos = pos;
f(); return input.substr(p_pos, pos-p_pos);
}
// syntax: <expression>?
// example: start = 'f'? (. .)?
function maybe(f) {
var missed = 0,
res = safe(f, function() { missed = 1; });
if (missed) return '';
return res;
}
// syntax: <expression>+
// example: start = 'f'? .+
function some(f) {
return [f()].concat(any(f)());
}
// syntax: <expression>*
// example: start = 'f'+ 'o'*
function any(f) {
var s = [],
missed = 0,
on_miss = function() { missed = 1; }
while (!missed) {
s.push(safe(f, on_miss));
}
if (missed) s.splice(-1);
return s;
}
// syntax: &<expression>
// example: start = &'f' 'foo'
function and(f) {
var p_pos = pos, missed = 0;
nr = 1; safe(f, function() {
missed = 1;
}); nr = 0;
pos = p_pos;
if (missed) failed(EOI, cc());
return '';
}
// syntax: !<expression>
// example: start = !'g' 'foo'
function not(f) {
var p_pos = pos, missed = 0;
nr = 1; safe(f, function() {
missed = 1;
}); nr = 0;
pos = p_pos;
if (missed) return '';
failed(EOI, cc());
}
// syntax: <expression_1> <expression_2> ...
// example: start = . 'oo'
function seqnc(/*f...*/) {
var ppos = pos;
var fs = arguments,
s = [],
on_miss = function(e) {
pos = ppos; throw e; };
for (var fi = 0; fl = fs.length;
fi < fl; fi++) {
s.push(safe(fs[fi], on_miss));
}
return s;
}
// syntax: <expression_1> / <expression_2> / ...
// example: start = . ('aa' / 'oo' / 'ee') .
function choice(/*f...*/) {
var fs = arguments,
missed = 0,
my_e = null,
on_miss = function(e) { my_e = e; missed = 1; };
for (var fi = 0, fl = fs.length;
fi < fl; fi++) {
var res = safe(fs[fi], on_miss);
if (!missed) return res;
missed = 0;
}
throw my_e;
}
// syntax: <expression> { <javascript-code> }
// example: start = 'fo' (. { return offset(); })
function action(f, code) {
function inctx(function() {
ppos = pos; var res;
f(); res = code(cctx);
if (res === null) { pos = ppos;
failed(SOMETHING, NOTHING); }
return res;
});
}
// syntax: & { <javascript-code> }
// example: start = &{ return true; } 'foo'
function pre(code) {
ppos = pos;
return code(cctx) ? '' : failed(cc(), EOI);
}
// syntax: ! { <javascript-code> }
// example: start = !{ return false; } 'foo'
function xpre(code) {
ppos = pos;
return code(cctx) ? failed(cc(), EOI) : '';
}
// syntax: <name>:<expression>
// example: start = a:. 'oo' { return a + 'bb'; }
function label(lbl, f) {
return cctx[lbl] = f();
}
// syntax: <rule_name> = <expression>
// example: space = " "
// foo "three symbols" = . . .
// start = !space foo !space
rules.<rule_name> = function() {
return (<root_operator_code>)();
}
// syntax: <rule_name>
// example: fo_rule = 'fo'
// start = fo_rule 'o'
function ref = inctx;
// syntax: <rule_name> "<alias>" = <expression>
// example: start "blah" = 'bar'
function as(name, f) {
alias = name; var res = f();
alias = ''; return res;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment