From c755dc3ed97532a2ce34cdb1c6ff9e407b9764a5 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Tue, 8 Jan 2013 17:00:54 +0100 Subject: [PATCH] Added some more detailed error messages in parser --- Objective-J/acorn.js | 71 ++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/Objective-J/acorn.js b/Objective-J/acorn.js index dffd4c9bc..ecb45a35f 100644 --- a/Objective-J/acorn.js +++ b/Objective-J/acorn.js @@ -1080,11 +1080,11 @@ if (!exports.acorn) { } // Expect a token of a given type. If found, consume it, otherwise, - // raise an unexpected token error. + // raise with errorMessage or an unexpected token error. - function expect(type) { + function expect(type, errorMessage) { if (tokType === type) next(); - else unexpected(); + else errorMessage ? raise(tokStart, errorMessage) : unexpected(); } // Raise an unexpected token error. @@ -1184,7 +1184,7 @@ if (!exports.acorn) { labels.push(loopLabel); node.body = parseStatement(); labels.pop(); - expect(_while); + expect(_while, "Expected 'while' at end of do statement"); node.test = parseParenExpression(); semicolon(); return finishNode(node, "DoWhileStatement"); @@ -1200,7 +1200,7 @@ if (!exports.acorn) { case _for: next(); labels.push(loopLabel); - expect(_parenL); + expect(_parenL, "Expected '(' after 'for'"); if (tokType === _semi) return parseFor(node, null); if (tokType === _var) { var init = startNode(); @@ -1241,7 +1241,7 @@ if (!exports.acorn) { next(); node.discriminant = parseParenExpression(); node.cases = []; - expect(_braceL); + expect(_braceL, "Expected '{' in switch statement"); labels.push(switchLabel); // Statements under must be grouped (by label) in SwitchCase @@ -1260,7 +1260,7 @@ if (!exports.acorn) { if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true; cur.test = null; } - expect(_colon); + expect(_colon, "Expected ':' after case clause"); } else { if (!cur) unexpected(); cur.consequent.push(parseStatement()); @@ -1286,11 +1286,11 @@ if (!exports.acorn) { while (tokType === _catch) { var clause = startNode(); next(); - expect(_parenL); + expect(_parenL, "Expected '(' after 'catch'"); clause.param = parseIdent(); if (strict && isStrictBadIdWord(clause.param.name)) raise(clause.param.start, "Binding " + clause.param.name + " in strict mode"); - expect(_parenR); + expect(_parenR, "Expected closing ')' after catch"); clause.guard = null; clause.body = parseBlock(); node.handlers.push(finishNode(clause, "CatchClause")); @@ -1337,7 +1337,7 @@ if (!exports.acorn) { node.superclassname = parseIdent(true); else if (eat(_parenL)) { node.categoryname = parseIdent(true); - expect(_parenR); + expect(_parenR, "Expected closing ')' after category name"); } if (eat(_braceL)) { node.ivardeclarations = []; @@ -1349,6 +1349,7 @@ if (!exports.acorn) { } node.body = []; while(!eat(_end)) { + if (tokType === _eof) raise(tokPos, "Expected '@end' after '@implementation'"); node.body.push(parseClassElement()); } } @@ -1430,12 +1431,12 @@ if (!exports.acorn) { switch(config.name) { case "property": case "getter": - expect(_eq); + expect(_eq, "Expected '=' after 'getter' accessor attribute"); decl.accessors[config.name] = parseIdent(true); break; case "setter": - expect(_eq); + expect(_eq, "Expected '=' after 'setter' accessor attribute"); var setter = parseIdent(true); decl.accessors[config.name] = setter; if (eat(_colon)) @@ -1454,7 +1455,7 @@ if (!exports.acorn) { } if (!eat(_comma)) break; } - expect(_parenR); + expect(_parenR, "Expected closing ')' after accessor attributes"); } } } @@ -1476,7 +1477,7 @@ if (!exports.acorn) { element.action = true; if (!eat(_parenR)) { element.returntype = parseObjectiveJType(); - expect(_parenR); + expect(_parenR, "Expected closing ')' after method return type"); } } // Now we parse the selector @@ -1491,17 +1492,17 @@ if (!exports.acorn) { if (first && tokType !== _colon) break; } else selectors.push(null); - expect(_colon); + expect(_colon, "Expected ':' in selector"); var argument = {}; args.push(argument); if (eat(_parenL)) { argument.type = parseObjectiveJType(); - expect(_parenR); + expect(_parenR, "Expected closing ')' after method argument type"); } argument.identifier = parseIdent(false); if (tokType === _braceL || eat(_semi)) break; if (eat(_comma)) { - expect(_dotdotdot); + expect(_dotdotdot, "Expected '...' after ',' in method declaration"); element.parameters = true; break; } @@ -1524,9 +1525,9 @@ if (!exports.acorn) { // parentheses around their expression. function parseParenExpression() { - expect(_parenL); + expect(_parenL, "Expected '(' before expression"); var val = parseExpression(); - expect(_parenR); + expect(_parenR, "Expected closing ')' after expression"); return val; } @@ -1537,7 +1538,7 @@ if (!exports.acorn) { function parseBlock(allowStrict) { var node = startNode(), first = true, strict = false, oldStrict; node.body = []; - expect(_braceL); + expect(_braceL, "Expected '{' before block"); while (!eat(_braceR)) { var stmt = parseStatement(); node.body.push(stmt); @@ -1557,11 +1558,11 @@ if (!exports.acorn) { function parseFor(node, init) { node.init = init; - expect(_semi); + expect(_semi, "Expected ';' in for statement"); node.test = tokType === _semi ? null : parseExpression(); - expect(_semi); + expect(_semi, "Expected ';' in for statement"); node.update = tokType === _parenR ? null : parseExpression(); - expect(_parenR); + expect(_parenR, "Expected closing ')' in for statement"); node.body = parseStatement(); labels.pop(); return finishNode(node, "ForStatement"); @@ -1572,7 +1573,7 @@ if (!exports.acorn) { function parseForIn(node, init) { node.left = init; node.right = parseExpression(); - expect(_parenR); + expect(_parenR, "Expected closing ')' in for statement"); node.body = parseStatement(); labels.pop(); return finishNode(node, "ForInStatement"); @@ -1643,7 +1644,7 @@ if (!exports.acorn) { var node = startNodeFrom(expr); node.test = expr; node.consequent = parseExpression(true); - expect(_colon); + expect(_colon, "Expected ':' in conditional expression"); node.alternate = parseExpression(true, noIn); return finishNode(node, "ConditionalExpression"); } @@ -1732,7 +1733,7 @@ if (!exports.acorn) { node.object = base; node.property = expr; node.computed = true; - expect(_bracketR); + expect(_bracketR, "Expected closing ']' in subscript"); return parseSubscripts(finishNode(node, "MemberExpression"), noCalls); } else if (!noCalls && eat(_parenL)) { var node = startNodeFrom(base); @@ -1778,7 +1779,7 @@ if (!exports.acorn) { } if (options.ranges) val.range = [tokStart1, tokEnd]; - expect(_parenR); + expect(_parenR, "Expected closing ')' in expression"); return val; case _bracketL: @@ -1807,9 +1808,9 @@ if (!exports.acorn) { case _selector: var node = startNode(); next(); - expect(_parenL); + expect(_parenL, "Expected '(' after '@selector'"); parseSelector(node, _parenR); - expect(_parenR); + expect(_parenR, "Expected closing ')' after selector"); return finishNode(node, "SelectorLiteralExpression"); default: @@ -1834,7 +1835,7 @@ if (!exports.acorn) { selectors.push(parseIdent(true).name); if (first && tokType === close) break; } - expect(_colon); + expect(_colon, "Expected ':' in selector"); selectors.push(":"); if (tokType === close) break; first = false; @@ -1857,7 +1858,7 @@ if (!exports.acorn) { } else { selectors.push(null); } - expect(_colon); + expect(_colon, "Expected ':' in selector"); args.push(parseExpression(true)); if (eat(close)) break; @@ -1895,7 +1896,7 @@ if (!exports.acorn) { next(); while (!eat(_braceR)) { if (!first) { - expect(_comma); + expect(_comma, "Expected ',' in object literal"); if (options.allowTrailingCommas && eat(_braceR)) break; } else first = false; @@ -1946,9 +1947,9 @@ if (!exports.acorn) { else node.id = null; node.params = []; var first = true; - expect(_parenL); + expect(_parenL, "Expected '(' before function parameters"); while (!eat(_parenR)) { - if (!first) expect(_comma); else first = false; + if (!first) expect(_comma, "Expected ',' between function parameters"); else first = false; node.params.push(parseIdent()); } @@ -1994,7 +1995,7 @@ if (!exports.acorn) { if (allowEmpty && tokType === _comma && !firstExpr) elts.push(null); else elts.push(firstExpr); } else { - expect(_comma); + expect(_comma, "Expected ',' between expressions"); if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break; if (allowEmpty && tokType === _comma) elts.push(null); else elts.push(parseExpression(true));