private AST ParseUnaryExpression(out bool isLeftHandSideExpr, ref bool canBeAttribute, bool isMinus, bool warnForKeyword){ AST ast = null; isLeftHandSideExpr = false; bool dummy = false; Context exprCtx = null; AST expr = null; switch (this.currentToken.token){ case JSToken.Void: exprCtx = this.currentToken.Clone(); GetNextToken(); canBeAttribute = false; expr = ParseUnaryExpression(out dummy, ref canBeAttribute, false); exprCtx.UpdateWith(expr.context); ast = new VoidOp(exprCtx, expr); break; case JSToken.Typeof: exprCtx = this.currentToken.Clone(); GetNextToken(); canBeAttribute = false; expr = ParseUnaryExpression(out dummy, ref canBeAttribute, false); exprCtx.UpdateWith(expr.context); ast = new Typeof(exprCtx, expr); break; case JSToken.Plus: exprCtx = this.currentToken.Clone(); GetNextToken(); canBeAttribute = false; expr = ParseUnaryExpression(out dummy, ref canBeAttribute, false); exprCtx.UpdateWith(expr.context); ast = new NumericUnary(exprCtx, expr, JSToken.Plus); break; case JSToken.Minus: exprCtx = this.currentToken.Clone(); GetNextToken(); canBeAttribute = false; expr = ParseUnaryExpression(out dummy, ref canBeAttribute, true); // deal with '-floatNumber' being parsed as a single entity (NumericLiteral) and not as a -NumericLiteral if (expr.context.token == JSToken.NumericLiteral){ exprCtx.UpdateWith(expr.context); expr.context = exprCtx; ast = expr; }else{ exprCtx.UpdateWith(expr.context); ast = new NumericUnary(exprCtx, expr, JSToken.Minus); } break; case JSToken.BitwiseNot: exprCtx = this.currentToken.Clone(); GetNextToken(); canBeAttribute = false; expr = ParseUnaryExpression(out dummy, ref canBeAttribute, false); exprCtx.UpdateWith(expr.context); ast = new NumericUnary(exprCtx, expr, JSToken.BitwiseNot); break; case JSToken.LogicalNot: exprCtx = this.currentToken.Clone(); GetNextToken(); canBeAttribute = false; expr = ParseUnaryExpression(out dummy, ref canBeAttribute, false); exprCtx.UpdateWith(expr.context); ast = new NumericUnary(exprCtx, expr, JSToken.LogicalNot); break; case JSToken.Delete: exprCtx = this.currentToken.Clone(); GetNextToken(); canBeAttribute = false; expr = ParseUnaryExpression(out dummy, ref canBeAttribute, false); exprCtx.UpdateWith(expr.context); ast = new Delete(exprCtx, expr); break; case JSToken.Increment: exprCtx = this.currentToken.Clone(); GetNextToken(); canBeAttribute = false; expr = ParseUnaryExpression(out dummy, ref canBeAttribute, false); exprCtx.UpdateWith(expr.context); ast = new PostOrPrefixOperator(exprCtx, expr, PostOrPrefix.PrefixIncrement); break; case JSToken.Decrement: exprCtx = this.currentToken.Clone(); GetNextToken(); canBeAttribute = false; expr = ParseUnaryExpression(out dummy, ref canBeAttribute, false); exprCtx.UpdateWith(expr.context); ast = new PostOrPrefixOperator(exprCtx, expr, PostOrPrefix.PrefixDecrement); break; default: this.noSkipTokenSet.Add(NoSkipTokenSet.s_PostfixExpressionNoSkipTokenSet); try{ ast = ParseLeftHandSideExpression(isMinus, ref canBeAttribute, warnForKeyword); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_PostfixExpressionNoSkipTokenSet, exc) == -1){ throw exc; }else{ if (exc._partiallyComputedNode == null) SkipTokensAndThrow(); else ast = exc._partiallyComputedNode; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_PostfixExpressionNoSkipTokenSet); } ast = ParsePostfixExpression(ast, out isLeftHandSideExpr, ref canBeAttribute); break; } dummy = dummy; return ast; }
private AST ParsePostfixExpression(AST ast, out bool isLeftHandSideExpr, ref bool canBeAttribute){ isLeftHandSideExpr = true; Context exprCtx = null; if (null != ast){ if (!this.scanner.GotEndOfLine()){ if (JSToken.Increment == this.currentToken.token){ isLeftHandSideExpr = false; exprCtx = ast.context.Clone(); exprCtx.UpdateWith(this.currentToken); canBeAttribute = false; ast = new PostOrPrefixOperator(exprCtx, ast, PostOrPrefix.PostfixIncrement); GetNextToken(); }else if (JSToken.Decrement == this.currentToken.token){ isLeftHandSideExpr = false; exprCtx = ast.context.Clone(); exprCtx.UpdateWith(this.currentToken); canBeAttribute = false; ast = new PostOrPrefixOperator(exprCtx, ast, PostOrPrefix.PostfixDecrement); GetNextToken(); } } } return ast; }
private AST ParseUnaryExpression(out bool isLeftHandSideExpr, ref bool canBeAttribute, bool isMinus, bool warnForKeyword) { AST ast = null; isLeftHandSideExpr = false; bool flag = false; Context context = null; AST operand = null; switch (this.currentToken.token) { case JSToken.FirstOp: context = this.currentToken.Clone(); this.GetNextToken(); canBeAttribute = false; operand = this.ParseUnaryExpression(out flag, ref canBeAttribute, false); context.UpdateWith(operand.context); ast = new NumericUnary(context, operand, JSToken.FirstOp); break; case JSToken.BitwiseNot: context = this.currentToken.Clone(); this.GetNextToken(); canBeAttribute = false; operand = this.ParseUnaryExpression(out flag, ref canBeAttribute, false); context.UpdateWith(operand.context); ast = new NumericUnary(context, operand, JSToken.BitwiseNot); break; case JSToken.Delete: context = this.currentToken.Clone(); this.GetNextToken(); canBeAttribute = false; operand = this.ParseUnaryExpression(out flag, ref canBeAttribute, false); context.UpdateWith(operand.context); ast = new Delete(context, operand); break; case JSToken.Void: context = this.currentToken.Clone(); this.GetNextToken(); canBeAttribute = false; operand = this.ParseUnaryExpression(out flag, ref canBeAttribute, false); context.UpdateWith(operand.context); ast = new VoidOp(context, operand); break; case JSToken.Typeof: context = this.currentToken.Clone(); this.GetNextToken(); canBeAttribute = false; operand = this.ParseUnaryExpression(out flag, ref canBeAttribute, false); context.UpdateWith(operand.context); ast = new Typeof(context, operand); break; case JSToken.Increment: context = this.currentToken.Clone(); this.GetNextToken(); canBeAttribute = false; operand = this.ParseUnaryExpression(out flag, ref canBeAttribute, false); context.UpdateWith(operand.context); ast = new PostOrPrefixOperator(context, operand, PostOrPrefix.PrefixIncrement); break; case JSToken.Decrement: context = this.currentToken.Clone(); this.GetNextToken(); canBeAttribute = false; operand = this.ParseUnaryExpression(out flag, ref canBeAttribute, false); context.UpdateWith(operand.context); ast = new PostOrPrefixOperator(context, operand, PostOrPrefix.PrefixDecrement); break; case JSToken.FirstBinaryOp: context = this.currentToken.Clone(); this.GetNextToken(); canBeAttribute = false; operand = this.ParseUnaryExpression(out flag, ref canBeAttribute, false); context.UpdateWith(operand.context); ast = new NumericUnary(context, operand, JSToken.FirstBinaryOp); break; case JSToken.Minus: context = this.currentToken.Clone(); this.GetNextToken(); canBeAttribute = false; operand = this.ParseUnaryExpression(out flag, ref canBeAttribute, true); if (operand.context.token != JSToken.NumericLiteral) { context.UpdateWith(operand.context); ast = new NumericUnary(context, operand, JSToken.Minus); break; } context.UpdateWith(operand.context); operand.context = context; ast = operand; break; default: this.noSkipTokenSet.Add(NoSkipTokenSet.s_PostfixExpressionNoSkipTokenSet); try { ast = this.ParseLeftHandSideExpression(isMinus, ref canBeAttribute, warnForKeyword); } catch (RecoveryTokenException exception) { if (this.IndexOfToken(NoSkipTokenSet.s_PostfixExpressionNoSkipTokenSet, exception) == -1) { throw exception; } if (exception._partiallyComputedNode == null) { this.SkipTokensAndThrow(); } else { ast = exception._partiallyComputedNode; } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_PostfixExpressionNoSkipTokenSet); } ast = this.ParsePostfixExpression(ast, out isLeftHandSideExpr, ref canBeAttribute); break; } return ast; }