Created
October 29, 2012 08:56
-
-
Save pasaran/3972474 to your computer and use it in GitHub Desktop.
parser.01
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
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>parser.01</title> | |
<script src="01.parser.js"></script> | |
</head> | |
<body> | |
<script> | |
var ast = parse('2 + 3 * (5 - 6)'); | |
console.log( JSON.stringify(ast, null, 4) ); | |
</script> | |
</body> | |
</html> | |
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
var TOKEN_ADD = /^[+-]/; | |
var TOKEN_MUL = /^[*/%]/; | |
var TOKEN_NUMBER = /^[0-9]+(\.[0-9]+)?/; | |
function parse(s) { | |
var p = 0; | |
var cur = s; | |
var ast = parse(r_expr); | |
if (cur) { | |
error('End of string expected'); | |
} | |
return ast; | |
// --------------------------------------------------------------------------------------------------------------- // | |
function parse(rule) { | |
var start = p; | |
var ast = rule(); | |
// ast._start = start; | |
// ast._end = p; | |
return ast; | |
} | |
function test(token) { | |
var r = token.exec(cur); | |
return r && r[0]; | |
} | |
function match(token) { | |
var result = test(token); | |
if (!result) { | |
expected(token); | |
} | |
move(result.length); | |
skip(); | |
return result; | |
} | |
function eat(s) { | |
var l = s.length; | |
if ( la(l) !== s ) { | |
expected(s); | |
} | |
move(l); | |
skip(); | |
return s; | |
} | |
function skip() { | |
var r = /^\s+/.exec(cur); | |
if (r) { | |
move(r[0].length); | |
} | |
} | |
function move(l) { | |
l || (l = 1); | |
p += l; | |
cur = cur.substr(l); | |
} | |
function la(n) { | |
return cur.substr(0, n || 1); | |
} | |
function expected(id) { | |
error('Token ' + id + 'expected'); | |
} | |
function error(msg) { | |
throw Error(msg + ' at ' + p + ' : ' + cur); | |
} | |
// --------------------------------------------------------------------------------------------------------------- // | |
function r_expr() { | |
return parse(r_add); | |
} | |
function r_add() { | |
var left = parse(r_mul); | |
if (( op = test(TOKEN_ADD) )) { | |
match(TOKEN_ADD); | |
return { | |
_id: 'add', | |
op: op, | |
left: left, | |
right: parse(r_add) | |
}; | |
} | |
return left; | |
} | |
function r_mul() { | |
var left = parse(r_primary); | |
if (( op = test(TOKEN_MUL) )) { | |
match(TOKEN_MUL); | |
return { | |
_id: 'mul', | |
op: op, | |
left: left, | |
right: parse(r_mul) | |
}; | |
} | |
return left; | |
} | |
function r_primary() { | |
if ( la() === '(' ) { | |
eat('('); | |
var ast = parse(r_expr); | |
eat(')'); | |
return ast; | |
} | |
return { | |
_id: 'number', | |
value: +match(TOKEN_NUMBER) | |
}; | |
} | |
// --------------------------------------------------------------------------------------------------------------- // | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment