def _parse_fold_or_paren_expression(self) -> ASTExpression:
    if (self.current_char != '('):
        return None
    self.pos += 1
    self.skip_ws()
    if self.skip_string_and_ws('...'):
        if (not self.match(_fold_operator_re)):
            self.fail("Expected fold operator after '...' in fold expression.")
        op = self.matched_text
        rightExpr = self._parse_cast_expression()
        if (not self.skip_string(')')):
            self.fail("Expected ')' in end of fold expression.")
        return ASTFoldExpr(None, op, rightExpr)
    pos = self.pos
    try:
        self.skip_ws()
        leftExpr = self._parse_cast_expression()
        self.skip_ws()
        if (not self.match(_fold_operator_re)):
            self.fail('Expected fold operator after left expression in fold expression.')
        op = self.matched_text
        self.skip_ws()
        if (not self.skip_string_and_ws('...')):
            self.fail("Expected '...' after fold operator in fold expression.")
    except DefinitionError as eFold:
        self.pos = pos
        try:
            res = self._parse_expression()
            self.skip_ws()
            if (not self.skip_string(')')):
                self.fail("Expected ')' in end of parenthesized expression.")
        except DefinitionError as eExpr:
            raise self._make_multi_error([(eFold, 'If fold expression'), (eExpr, 'If parenthesized expression')], 'Error in fold expression or parenthesized expression.')
        return ASTParenExpr(res)
    if self.skip_string(')'):
        return ASTFoldExpr(leftExpr, op, None)
    if (not self.match(_fold_operator_re)):
        self.fail("Expected fold operator or ')' after '...' in fold expression.")
    if (op != self.matched_text):
        self.fail(("Operators are different in binary fold: '%s' and '%s'." % (op, self.matched_text)))
    rightExpr = self._parse_cast_expression()
    self.skip_ws()
    if (not self.skip_string(')')):
        self.fail("Expected ')' to end binary fold expression.")
    return ASTFoldExpr(leftExpr, op, rightExpr)
def _parse_fold_or_paren_expression(self) -> ASTExpression:
    if (self.current_char != '('):
        return None
    self.pos += 1
    self.skip_ws()
    if self.skip_string_and_ws('...'):
        if (not self.match(_fold_operator_re)):
            self.fail("Expected fold operator after '...' in fold expression.")
        op = self.matched_text
        rightExpr = self._parse_cast_expression()
        if (not self.skip_string(')')):
            self.fail("Expected ')' in end of fold expression.")
        return ASTFoldExpr(None, op, rightExpr)
    pos = self.pos
    try:
        self.skip_ws()
        leftExpr = self._parse_cast_expression()
        self.skip_ws()
        if (not self.match(_fold_operator_re)):
            self.fail('Expected fold operator after left expression in fold expression.')
        op = self.matched_text
        self.skip_ws()
        if (not self.skip_string_and_ws('...')):
            self.fail("Expected '...' after fold operator in fold expression.")
    except DefinitionError as eFold:
        self.pos = pos
        try:
            res = self._parse_expression()
            self.skip_ws()
            if (not self.skip_string(')')):
                self.fail("Expected ')' in end of parenthesized expression.")
        except DefinitionError as eExpr:
            raise self._make_multi_error([(eFold, 'If fold expression'), (eExpr, 'If parenthesized expression')], 'Error in fold expression or parenthesized expression.')
        return ASTParenExpr(res)
    if self.skip_string(')'):
        return ASTFoldExpr(leftExpr, op, None)
    if (not self.match(_fold_operator_re)):
        self.fail("Expected fold operator or ')' after '...' in fold expression.")
    if (op != self.matched_text):
        self.fail(("Operators are different in binary fold: '%s' and '%s'." % (op, self.matched_text)))
    rightExpr = self._parse_cast_expression()
    self.skip_ws()
    if (not self.skip_string(')')):
        self.fail("Expected ')' to end binary fold expression.")
    return ASTFoldExpr(leftExpr, op, rightExpr)