From 5f42326f34a1e2ee2f43fb69a07cd2746de08df6 Mon Sep 17 00:00:00 2001 From: Charlie Somerville Date: Sun, 18 Jan 2015 00:44:14 +1100 Subject: [PATCH 1/2] set the rightAssociative flag on _exponent --- acorn.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acorn.js b/acorn.js index 692e6c6796..a3be8bdb90 100644 --- a/acorn.js +++ b/acorn.js @@ -469,7 +469,7 @@ // '*' may be multiply or have special meaning in ES6 var _star = {binop: 10, beforeExpr: true}; - var _exponent = {binop: 11, beforeExpr: true}; + var _exponent = {binop: 11, beforeExpr: true, rightAssociative: true}; // '<', '>' may be relational or have special meaning in JSX var _lt = {binop: 7, beforeExpr: true}, _gt = {binop: 7, beforeExpr: true}; From b51118c3fcd05cbd0cce58826f4c561a3a57e3d3 Mon Sep 17 00:00:00 2001 From: Charlie Somerville Date: Sun, 18 Jan 2015 00:42:43 +1100 Subject: [PATCH 2/2] use right recursion for right associative operators --- acorn.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/acorn.js b/acorn.js index a3be8bdb90..3cf3f06e87 100644 --- a/acorn.js +++ b/acorn.js @@ -2515,9 +2515,17 @@ var op = tokType; next(); var start = storeCurrentPos(); - node.right = parseExprOp(parseMaybeUnary(), start, prec, noIn); + if(op.rightAssociative) { + node.right = parseExprOp(parseMaybeUnary(), start, prec - 1, noIn); + } else { + node.right = parseExprOp(parseMaybeUnary(), start, prec, noIn); + } finishNode(node, (op === _logicalOR || op === _logicalAND) ? "LogicalExpression" : "BinaryExpression"); - return parseExprOp(node, leftStart, minPrec, noIn); + if(op.rightAssociative) { + return node; + } else { + return parseExprOp(node, leftStart, minPrec, noIn); + } } } return left;