From f3d392bd1cb3bd6a656e656e6919817178d9ab65 Mon Sep 17 00:00:00 2001 From: David Majda Date: Sat, 31 Aug 2013 11:02:00 +0200 Subject: [PATCH] JavaScript example: Fix handling of elided elements in array literals JavaScript allows one to skip (elide) elements in array literals. It also allows a trailing comma, which doesn't imply an element elision. For example, an array literal: [,,,] contains three elided elements (one before each comma) and a trailing comma. Example JavaScript parser handled elided elements incorrectly and just threw them away. This commit fixes this behvior and inserts |null| in the AST for each elided element. This is in line with how SpiderMonkey's JavaScript parser (the |Reflect.parse| API), Esprima and Acorn behave. Based on a patch by @fpirsch: https://github.com/dmajda/pegjs/pull/177 --- examples/javascript.pegjs | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/examples/javascript.pegjs b/examples/javascript.pegjs index 62f0e5c..370ee25 100644 --- a/examples/javascript.pegjs +++ b/examples/javascript.pegjs @@ -475,32 +475,45 @@ PrimaryExpression / "(" __ expression:Expression __ ")" { return expression; } ArrayLiteral - = "[" __ (Elision __)? "]" { + = "[" __ elision:(Elision __)? "]" { return { type: "ArrayLiteral", - elements: [] + elements: elision !== "" ? elision[0] : [] }; } - / "[" __ elements:ElementList __ ("," __ (Elision __)?)? "]" { + / "[" __ elements:ElementList __ elision:("," __ (Elision __)?)? "]" { return { type: "ArrayLiteral", - elements: elements + elements: elements.concat(elision !== "" && elision[2] !== "" ? elision[2][0] : []) }; } ElementList - = (Elision __)? - head:AssignmentExpression - tail:(__ "," __ (Elision __)? AssignmentExpression)* { - var result = [head]; + = head:( + elision:(Elision __)? element:AssignmentExpression { + return (elision !== "" ? elision[0] : []).concat(element); + } + ) + tail:( + __ "," __ elision:(Elision __)? element:AssignmentExpression { + return (elision !== "" ? elision[0] : []).concat(element); + } + )* { + var result = head; for (var i = 0; i < tail.length; i++) { - result.push(tail[i][4]); + result = result.concat(tail[i]); } return result; } Elision - = "," (__ ",")* + = "," elision:(__ ",")* { + var result = [null]; + for (var i = 0; i < elision.length; i++) { + result.push(null); + } + return result; + } ObjectLiteral = "{" __ properties:(PropertyNameAndValueList __ ("," __)?)? "}" {