public bool Visit(UnaryOperator node) { if (node.SymType != null) { return(true); } node.Expr.Accept(this); switch (node.Token.Type) { case TokenType.SumOperator: case TokenType.DifOperator: { if (!(node.Expr.SymType.Equals(SymbolStack.SymInt) || node.Expr.SymType.Equals(SymbolStack.SymFloat))) { throw new Exception(string.Format( "({0}, {1}) semantic error: 'integer' or 'float' expected, but '{2}' found", node.Expr.Token.Line, node.Expr.Token.Column, node.Expr.Token.Lexeme)); } node.SymType = node.Expr.SymType; break; } case TokenType.AtSign: { if (!node.Expr.IsLValue) { throw new Exception(string.Format( "({0}, {1}) semantic error: expression '{2}' is not lvalue", node.Expr.Token.Line, node.Expr.Token.Column, node.Expr.ToString())); } node.SymType = _symStack.SymTypeToSymPointerType(node.Expr.SymType); break; } case TokenType.Not: { if (!node.Expr.SymType.Equals(SymbolStack.SymBool)) { throw new Exception(string.Format( "({0}, {1}) semantic error: boolean expected, but '{2}' found", node.Expr.Token.Line, node.Expr.Token.Column, node.Expr.ToString())); } node.SymType = node.Expr.SymType; break; } default: { throw new Exception(string.Format( "({0}, {1}) semantic error: unrecognized unary operator '{2}'", node.Token.Line, node.Token.Column, node.ToString())); } } node.IsLValue = false; return(true); }