def _parse_unary_expression(self) -> ASTExpression:
    self.skip_ws()
    for op in _expression_unary_ops:
        if (op[0] in 'cn'):
            res = self.skip_word(op)
        else:
            res = self.skip_string(op)
        if res:
            expr = self._parse_cast_expression()
            return ASTUnaryOpExpr(op, expr)
    if self.skip_word_and_ws('sizeof'):
        if self.skip_string_and_ws('...'):
            if (not self.skip_string_and_ws('(')):
                self.fail("Expecting '(' after 'sizeof...'.")
            if (not self.match(identifier_re)):
                self.fail("Expecting identifier for 'sizeof...'.")
            ident = ASTIdentifier(self.matched_text)
            self.skip_ws()
            if (not self.skip_string(')')):
                self.fail("Expecting ')' to end 'sizeof...'.")
            return ASTSizeofParamPack(ident)
        if self.skip_string_and_ws('('):
            typ = self._parse_type(named=False)
            self.skip_ws()
            if (not self.skip_string(')')):
                self.fail("Expecting ')' to end 'sizeof'.")
            return ASTSizeofType(typ)
        expr = self._parse_unary_expression()
        return ASTSizeofExpr(expr)
    if self.skip_word_and_ws('alignof'):
        if (not self.skip_string_and_ws('(')):
            self.fail("Expecting '(' after 'alignof'.")
        typ = self._parse_type(named=False)
        self.skip_ws()
        if (not self.skip_string(')')):
            self.fail("Expecting ')' to end 'alignof'.")
        return ASTAlignofExpr(typ)
    if self.skip_word_and_ws('noexcept'):
        if (not self.skip_string_and_ws('(')):
            self.fail("Expecting '(' after 'noexcept'.")
        expr = self._parse_expression()
        self.skip_ws()
        if (not self.skip_string(')')):
            self.fail("Expecting ')' to end 'noexcept'.")
        return ASTNoexceptExpr(expr)
    pos = self.pos
    rooted = self.skip_string('::')
    self.skip_ws()
    if (not self.skip_word_and_ws('new')):
        self.pos = pos
    else:
        isNewTypeId = True
        if self.skip_string_and_ws('('):
            self.fail('Sorry, neither new-placement nor parenthesised type-id in new-epression is supported yet.')
        if isNewTypeId:
            declSpecs = self._parse_decl_specs(outer=None)
            decl = self._parse_declarator(named=False, paramMode='new')
        else:
            self.fail('Sorry, parenthesised type-id in new expression not yet supported.')
        lst = self._parse_expression_list_or_braced_init_list()
        return ASTNewExpr(rooted, isNewTypeId, ASTType(declSpecs, decl), lst)
    pos = self.pos
    rooted = self.skip_string('::')
    self.skip_ws()
    if (not self.skip_word_and_ws('delete')):
        self.pos = pos
    else:
        array = self.skip_string_and_ws('[')
        if (array and (not self.skip_string_and_ws(']'))):
            self.fail("Expected ']' in array delete-expression.")
        expr = self._parse_cast_expression()
        return ASTDeleteExpr(rooted, array, expr)
    return self._parse_postfix_expression()
def _parse_unary_expression(self) -> ASTExpression:
    self.skip_ws()
    for op in _expression_unary_ops:
        if (op[0] in 'cn'):
            res = self.skip_word(op)
        else:
            res = self.skip_string(op)
        if res:
            expr = self._parse_cast_expression()
            return ASTUnaryOpExpr(op, expr)
    if self.skip_word_and_ws('sizeof'):
        if self.skip_string_and_ws('...'):
            if (not self.skip_string_and_ws('(')):
                self.fail("Expecting '(' after 'sizeof...'.")
            if (not self.match(identifier_re)):
                self.fail("Expecting identifier for 'sizeof...'.")
            ident = ASTIdentifier(self.matched_text)
            self.skip_ws()
            if (not self.skip_string(')')):
                self.fail("Expecting ')' to end 'sizeof...'.")
            return ASTSizeofParamPack(ident)
        if self.skip_string_and_ws('('):
            typ = self._parse_type(named=False)
            self.skip_ws()
            if (not self.skip_string(')')):
                self.fail("Expecting ')' to end 'sizeof'.")
            return ASTSizeofType(typ)
        expr = self._parse_unary_expression()
        return ASTSizeofExpr(expr)
    if self.skip_word_and_ws('alignof'):
        if (not self.skip_string_and_ws('(')):
            self.fail("Expecting '(' after 'alignof'.")
        typ = self._parse_type(named=False)
        self.skip_ws()
        if (not self.skip_string(')')):
            self.fail("Expecting ')' to end 'alignof'.")
        return ASTAlignofExpr(typ)
    if self.skip_word_and_ws('noexcept'):
        if (not self.skip_string_and_ws('(')):
            self.fail("Expecting '(' after 'noexcept'.")
        expr = self._parse_expression()
        self.skip_ws()
        if (not self.skip_string(')')):
            self.fail("Expecting ')' to end 'noexcept'.")
        return ASTNoexceptExpr(expr)
    pos = self.pos
    rooted = self.skip_string('::')
    self.skip_ws()
    if (not self.skip_word_and_ws('new')):
        self.pos = pos
    else:
        isNewTypeId = True
        if self.skip_string_and_ws('('):
            self.fail('Sorry, neither new-placement nor parenthesised type-id in new-epression is supported yet.')
        if isNewTypeId:
            declSpecs = self._parse_decl_specs(outer=None)
            decl = self._parse_declarator(named=False, paramMode='new')
        else:
            self.fail('Sorry, parenthesised type-id in new expression not yet supported.')
        lst = self._parse_expression_list_or_braced_init_list()
        return ASTNewExpr(rooted, isNewTypeId, ASTType(declSpecs, decl), lst)
    pos = self.pos
    rooted = self.skip_string('::')
    self.skip_ws()
    if (not self.skip_word_and_ws('delete')):
        self.pos = pos
    else:
        array = self.skip_string_and_ws('[')
        if (array and (not self.skip_string_and_ws(']'))):
            self.fail("Expected ']' in array delete-expression.")
        expr = self._parse_cast_expression()
        return ASTDeleteExpr(rooted, array, expr)
    return self._parse_postfix_expression()