Cleanup parser code to expose smaller API

This commit is contained in:
Misko Hevery
2011-04-05 11:00:26 -07:00
parent bb67ee8d28
commit 0e17ade959
7 changed files with 31 additions and 54 deletions

View File

@@ -35,19 +35,14 @@ function toJson(obj, pretty) {
function fromJson(json, useNative) {
if (!isString(json)) return json;
var obj, p, expression;
var obj;
try {
if (useNative && window.JSON && window.JSON.parse) {
obj = JSON.parse(json);
return transformDates(obj);
}
p = parser(json, true);
expression = p.primary();
p.assertAllConsumed();
return expression();
return parser(json, true).primary()();
} catch (e) {
error("fromJson error: ", json, e);
throw e;

View File

@@ -92,7 +92,6 @@ function expressionCompile(exp){
if (!fn) {
var p = parser(exp);
var fnSelf = p.statements();
p.assertAllConsumed();
fn = compileCache[exp] = extend(
function(){ return fnSelf(this);},
{fnSelf: fnSelf});

View File

@@ -240,22 +240,29 @@ function parser(text, json){
function (){ throwError("is not valid json", {text:text, index:0}); };
}
return {
assertAllConsumed: assertAllConsumed,
assignable: assignable,
primary: primary,
statements: statements,
validator: validator,
formatter: formatter,
filter: filter,
//TODO: delete me, since having watch in UI is logic in UI. (leftover form getangular)
watch: watch
assignable: assertConsumed(assignable),
primary: assertConsumed(primary),
statements: assertConsumed(statements),
validator: assertConsumed(validator),
formatter: assertConsumed(formatter),
filter: assertConsumed(filter)
};
function assertConsumed(fn) {
return function(){
var value = fn();
if (tokens.length !== 0) {
throwError("is an unexpected token", tokens[0]);
}
return value;
};
}
///////////////////////////////////
function throwError(msg, token) {
throw Error("Parse Error: Token '" + token.text +
throw Error("Syntax Error: Token '" + token.text +
"' " + msg + " at column " +
(token.index + 1) + " of expression [" +
(token.index + 1) + " of the expression [" +
text + "] starting at [" + text.substring(token.index) + "].");
}
@@ -313,12 +320,6 @@ function parser(text, json){
return tokens.length > 0;
}
function assertAllConsumed(){
if (tokens.length !== 0) {
throwError("is extra token not part of expression", tokens[0]);
}
}
function statements(){
var statements = [];
while(true) {
@@ -639,24 +640,6 @@ function parser(text, json){
};
}
//TODO: delete me, since having watch in UI is logic in UI. (leftover form getangular)
function watch () {
var decl = [];
while(hasTokens()) {
decl.push(watchDecl());
if (!expect(';')) {
assertAllConsumed();
}
}
assertAllConsumed();
return function (self){
for ( var i = 0; i < decl.length; i++) {
var d = decl[i](self);
self.addListener(d.name, d.fn);
}
};
}
function watchDecl () {
var anchorName = expect().text;
consume(":");