Skip to content

Instantly share code, notes, and snippets.

@wizardforcel
Created August 23, 2016 01:50
Show Gist options
  • Save wizardforcel/c62cb538fdd5d8986d5ff1e63d6de3d7 to your computer and use it in GitHub Desktop.
Save wizardforcel/c62cb538fdd5d8986d5ff1e63d6de3d7 to your computer and use it in GitHub Desktop.
tokenRE = /^[A-Za-z_]\w{0,31}/;
numeralRE = /^\d+/;
function matchAndReturn(str, re) {
var r = str.match(re);
return r? r[0]: null;
}
isToken = s => matchAndReturn(s, tokenRE);
isNumeral = s => matchAndReturn(s, numeralRE);
function parse(expr) {
var r = parseExpr(expr, 0);
return r? r[0]: null;
}
function skipBlank(expr, at) {
while(expr[at] === ' ')
at++;
return at;
}
function parseExpr(expr, at) {
at = skipBlank(expr, at);
//literal
var r = isNumeral(expr.substr(at));
if(r) {
at += r.length;
return [parseInt(r), at];
}
//call
return parseCall(expr, at);
}
function parseCall(expr, at) {
var arr = [];
//operator
at = skipBlank(expr, at);
var r = isToken(expr.substr(at));
if(!r) return null;
arr.push(r);
at += r.length;
//'('
at = skipBlank(expr, at);
if(expr[at] != '(')
return null;
at += 1;
//operand 1
at = skipBlank(expr, at);
r = parseExpr(expr, at);
if(!r) return null;
at = r[1];
arr.push(r[0]);
//other operands
while(true) {
//','
at = skipBlank(expr, at);
if(expr[at] != ',')
break;
at += 1;
//operand
at = skipBlank(expr, at);
r = parseExpr(expr, at);
if(!r) return null;
at = r[1];
arr.push(r[0]);
}
//')'
at = skipBlank(expr, at);
if(expr[at] != ')')
return null;
at += 1;
return [arr, at];
}
parse("mul(add(sub(1, 2), 3), 4)");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment