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 { diff --git a/print.js b/print.js index 38086d1..03020eb 100644 --- a/print.js +++ b/print.js @@ -1,8 +1,60 @@ "use strict"; +var nonCommutative = [ "-" , "/" , "%" ]; +var precedence = [ // from less to most preferent + [ "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "&=", "^=", "|=" ], + "||", + "&&", + "|", + "^", + "&", + [ "<", "<=", ">", ">=", "in", "instanceof" ], + [ "<<", ">>", ">>>" ], + [ "+", "-" ], + [ "*", "/", "%" ], + [ "!", "~", "+unary", "-unary", "typeof", "void", "delete" ], + [ "++", "--" ] +]; + (function(parser) { var ast = parser.ast; + function needBrackets(parentToken, childToken, childPrecedesParent) { + var firstOp = parentToken.operator; + if (parentToken.type === "UnaryExpression" && + (parentToken.operator === "-" || parentToken.operator === "+")) { + firstOp += "unary"; + } + var secondOp = childToken.operator; + if (childToken.type == "UnaryExpression" && + (childToken.operator === "-" || childToken.operator === "+")) { + secondOp += "unary"; + } + if (!childPrecedesParent && childToken.type == "BinaryExpression") { + for (var i=0; i secondPos; + } + ast.ProgramNode.prototype.print = function(indent, indentChar) { var elements = this.body; var str = ""; @@ -392,29 +444,79 @@ 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, true)) { + 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, true)) { + 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) { @@ -497,3 +599,4 @@ return this.value; }; })(ecmascript); +