int PeekNextToken() { BeginPeekToken(); int re = GetNextToken(); EndPeekToken(); return re; }
/** * unary-expression: * postfix-expression * unary-operator unary-expression * ( type-name ) unary-expression * sizeof unary-expression * sizeof ( type-name ) * * unary-operator: * ++ -- & * + - ! ~ */ static AstExpression ParseUnaryExpression() { AstExpression expr; int t; switch (CurrentToken) { case TK_INC: case TK_DEC: case TK_BITAND: case TK_MUL: case TK_ADD: case TK_SUB: case TK_NOT: case TK_COMP: CREATE_AST_NODE(expr, Expression); expr->op = UNARY_OP; NEXT_TOKEN; expr->kids[0] = ParseUnaryExpression(); return expr; case TK_LPAREN: /// When current token is (, it may be a type cast expression /// or a primary expression, we need to look ahead one token, /// if next token is type name, the expression is treated as /// a type cast expression; otherwise a primary expresion BeginPeekToken(); t = GetNextToken(); if (IsTypeName(t)) { EndPeekToken(); CREATE_AST_NODE(expr, Expression); expr->op = OP_CAST; NEXT_TOKEN; expr->kids[0] = (AstExpression)ParseTypeName(); Expect(TK_RPAREN); expr->kids[1] = ParseUnaryExpression(); return expr; } else { EndPeekToken(); return ParsePostfixExpression(); } break; case TK_SIZEOF: /// this case hase the same issue with TK_LPAREN case CREATE_AST_NODE(expr, Expression); expr->op = OP_SIZEOF; NEXT_TOKEN; if (CurrentToken == TK_LPAREN) { BeginPeekToken(); t = GetNextToken(); if (IsTypeName(t)) { EndPeekToken(); NEXT_TOKEN; /// In this case, the first kid is not an expression, /// but thanks to both type name and expression have a /// kind member to discriminate them. expr->kids[0] = (AstExpression)ParseTypeName(); Expect(TK_RPAREN); } else { EndPeekToken(); expr->kids[0] = ParseUnaryExpression(); } } else { expr->kids[0] = ParseUnaryExpression(); } return expr; default: return ParsePostfixExpression(); } }