From 59ee37bf6320a32c484c64585b8b876acf9797b6 Mon Sep 17 00:00:00 2001 From: jacobo221 Date: Tue, 11 Mar 2014 23:32:56 +0100 Subject: [PATCH 1/4] New feature: Do not include all brackets, just the minimum needed to keep precedences --- print.js | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 6 deletions(-) diff --git a/print.js b/print.js index 38086d1..6f6c2b9 100644 --- a/print.js +++ b/print.js @@ -3,6 +3,45 @@ (function(parser) { var ast = parser.ast; + function needBrackets(firstToken,secondToken) { + var firstOp = firstToken.operator; + if ((firstToken.type == "UnaryExpression") && + (firstToken.operator == "-" || firstToken.operator == "+")) { + firstOp += "unary"; + } + var secondOp = secondToken.operator; + if ((secondToken.type == "UnaryExpression") && + (secondToken.operator == "-" || secondToken.operator == "+")) { + secondOp += "unary"; + } + var precedence = new Array( // from less to most preferent + new Array("=","+=","-=","*=","/=","%=","<<=",">>=",">>>=","&=","^=","|="), + "||", + "&&", + "|", + "^", + "&", + new Array("<","<=",">",">=","in","instanceof"), + new Array("<<",">>",">>>"), + new Array("+","-"), + new Array("*","/","%"), + new Array("!","~","+unary","-unary","typeof","void","delete"), + new Array("++","--") + ); + var firstPos = precedence.length, secondPos = precedence.length; + for (var i=0;i secondPos); + } + ast.ProgramNode.prototype.print = function(indent, indentChar) { var elements = this.body; var str = ""; @@ -392,29 +431,66 @@ if (operator === "delete" || operator === "void" || operator === "typeof") { return operator + " (" + this.argument.print("", "") + ")"; - } else { + } else if (needBrackets(this, this.argument)) { return operator + "(" + this.argument.print("", "") + ")"; + } else { + return operator + this.argument.print("", "") } }; ast.BinaryExpressionNode.prototype.print = function(indent, indentChar) { - return "(" + this.left.print("", "") + ") " + this.operator + " (" + this.right.print("", "") + ")"; + var str = ""; + if (needBrackets(this,this.left)) { + str += "(" + this.left.print("", "") + ")"; + } else { + str += this.left.print("", ""); + } + str += " " + this.operator + " "; + if (needBrackets(this,this.right)) { + str += "(" + this.right.print("", "") + ")"; + } else { + str += this.right.print("", ""); + } + return str; }; ast.AssignmentExpressionNode.prototype.print = function(indent, indentChar) { - return this.left.print("", "") + " " + this.operator + " (" + this.right.print("", "") + ")"; + var str = this.left.print("", "") + " " + this.operator + " "; + if (needBrackets(this,this.right)) { + str += "(" + this.right.print("", "") + ")"; + } else { + str += this.right.print("", ""); + } + return str; }; ast.UpdateExpressionNode.prototype.print = function(indent, indentChar) { + var str = this.argument.print("", ""); + if (needBrackets(this, this.argument)) { + str = "(" + str + ")"; + } if (this.prefix) { - return "(" + this.operator + this.argument.print("", "") + ")"; + str = this.operator + str; } else { - return "(" + this.argument.print("", "") + this.operator + ")"; + str = str + this.operator; } + return str; }; ast.LogicalExpressionNode.prototype.print = function(indent, indentChar) { - return "(" + this.left.print("", "") + ") " + this.operator + " (" + this.right.print("", "") + ")"; + var str = ""; + if (needBrackets(this,this.left)) { + str += "(" + this.left.print("", "") + ")"; + } else { + str += this.left.print("", ""); + } + str += " " + this.operator + " "; + if (needBrackets(this,this.right)) { + str += "(" + this.right.print("", "") + ")"; + } else { + str += this.right.print("", ""); + } + return str; }; ast.ConditionalExpressionNode.prototype.print = function(indent, indentChar) { From bea8b4764dc685799e41e4a477b9844343eb4b90 Mon Sep 17 00:00:00 2001 From: Jacobo221 Date: Fri, 6 Jun 2014 02:25:01 +0200 Subject: [PATCH 2/4] Fix parser discarding discarding the fractional part od a real number if the first digit is 0 --- ecmascript.jison | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecmascript.jison b/ecmascript.jison index fff7fbc..cdf1b79 100644 --- a/ecmascript.jison +++ b/ecmascript.jison @@ -1553,7 +1553,7 @@ function parseRegularExpressionLiteral(literal) { } function parseNumericLiteral(literal) { - if (literal.charAt(0) === "0") { + if (literal.charAt(0) === "0" && Number(literal)%1 === 0) { if (literal.charAt(1).toLowerCase() === "x") { return parseInt(literal, 16); } else { From d0a041744313b2497b63262e88cdb37d6da5c016 Mon Sep 17 00:00:00 2001 From: Jacobo221 Date: Fri, 6 Jun 2014 03:04:06 +0200 Subject: [PATCH 3/4] Applied coding style to previous patch ("Do not include all brackets") --- print.js | 81 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/print.js b/print.js index 6f6c2b9..fc4a51f 100644 --- a/print.js +++ b/print.js @@ -1,45 +1,50 @@ "use strict"; +var precedence = [ // from less to most preferent + [ "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "&=", "^=", "|=" ], + "||", + "&&", + "|", + "^", + "&", + [ "<", "<=", ">", ">=", "in", "instanceof" ], + [ "<<", ">>", ">>>" ], + [ "+", "-" ], + [ "*", "/", "%" ], + [ "!", "~", "+unary", "-unary", "typeof", "void", "delete" ], + [ "++", "--" ] +]; + (function(parser) { var ast = parser.ast; - function needBrackets(firstToken,secondToken) { + function needBrackets(firstToken, secondToken) { var firstOp = firstToken.operator; - if ((firstToken.type == "UnaryExpression") && - (firstToken.operator == "-" || firstToken.operator == "+")) { + if (firstToken.type === "UnaryExpression" && + (firstToken.operator === "-" || firstToken.operator === "+")) { firstOp += "unary"; } var secondOp = secondToken.operator; - if ((secondToken.type == "UnaryExpression") && - (secondToken.operator == "-" || secondToken.operator == "+")) { + if (secondToken.type == "UnaryExpression" && + (secondToken.operator === "-" || secondToken.operator === "+")) { secondOp += "unary"; } - var precedence = new Array( // from less to most preferent - new Array("=","+=","-=","*=","/=","%=","<<=",">>=",">>>=","&=","^=","|="), - "||", - "&&", - "|", - "^", - "&", - new Array("<","<=",">",">=","in","instanceof"), - new Array("<<",">>",">>>"), - new Array("+","-"), - new Array("*","/","%"), - new Array("!","~","+unary","-unary","typeof","void","delete"), - new Array("++","--") - ); - var firstPos = precedence.length, secondPos = precedence.length; - for (var i=0;i secondPos); + + return firstPos > secondPos; } ast.ProgramNode.prototype.print = function(indent, indentChar) { @@ -434,62 +439,75 @@ } else if (needBrackets(this, this.argument)) { return operator + "(" + this.argument.print("", "") + ")"; } else { - return operator + this.argument.print("", "") + return operator + this.argument.print("", ""); } }; ast.BinaryExpressionNode.prototype.print = function(indent, indentChar) { var str = ""; - if (needBrackets(this,this.left)) { + + if (needBrackets(this, this.left)) { str += "(" + this.left.print("", "") + ")"; } else { str += this.left.print("", ""); } + str += " " + this.operator + " "; - if (needBrackets(this,this.right)) { + + if (needBrackets(this, this.right)) { str += "(" + this.right.print("", "") + ")"; } else { str += this.right.print("", ""); } + return str; }; ast.AssignmentExpressionNode.prototype.print = function(indent, indentChar) { var str = this.left.print("", "") + " " + this.operator + " "; - if (needBrackets(this,this.right)) { + + if (needBrackets(this, this.right)) { str += "(" + this.right.print("", "") + ")"; } else { str += this.right.print("", ""); } + return str; }; ast.UpdateExpressionNode.prototype.print = function(indent, indentChar) { var str = this.argument.print("", ""); + if (needBrackets(this, this.argument)) { str = "(" + str + ")"; } + if (this.prefix) { str = this.operator + str; } else { str = str + this.operator; } + return str; }; ast.LogicalExpressionNode.prototype.print = function(indent, indentChar) { var str = ""; - if (needBrackets(this,this.left)) { + + if (needBrackets(this, this.left)) { str += "(" + this.left.print("", "") + ")"; } else { str += this.left.print("", ""); } + str += " " + this.operator + " "; - if (needBrackets(this,this.right)) { + + if (needBrackets(this, this.right)) { str += "(" + this.right.print("", "") + ")"; } else { str += this.right.print("", ""); } + return str; }; @@ -573,3 +591,4 @@ return this.value; }; })(ecmascript); + From d29a346e937c81036379c3b073c63aefe6c4fd3c Mon Sep 17 00:00:00 2001 From: Jacobo221 Date: Mon, 9 Jun 2014 00:32:06 +0200 Subject: [PATCH 4/4] Fix a brackets brackets simplifcation with non commutative operations (before it would consider 10/6/2 == 10/(6/2) --- print.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/print.js b/print.js index fc4a51f..03020eb 100644 --- a/print.js +++ b/print.js @@ -1,5 +1,6 @@ "use strict"; +var nonCommutative = [ "-" , "/" , "%" ]; var precedence = [ // from less to most preferent [ "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "&=", "^=", "|=" ], "||", @@ -18,17 +19,24 @@ var precedence = [ // from less to most preferent (function(parser) { var ast = parser.ast; - function needBrackets(firstToken, secondToken) { - var firstOp = firstToken.operator; - if (firstToken.type === "UnaryExpression" && - (firstToken.operator === "-" || firstToken.operator === "+")) { + function needBrackets(parentToken, childToken, childPrecedesParent) { + var firstOp = parentToken.operator; + if (parentToken.type === "UnaryExpression" && + (parentToken.operator === "-" || parentToken.operator === "+")) { firstOp += "unary"; } - var secondOp = secondToken.operator; - if (secondToken.type == "UnaryExpression" && - (secondToken.operator === "-" || secondToken.operator === "+")) { + var secondOp = childToken.operator; + if (childToken.type == "UnaryExpression" && + (childToken.operator === "-" || childToken.operator === "+")) { secondOp += "unary"; } + if (!childPrecedesParent && childToken.type == "BinaryExpression") { + for (var i=0; i