def read_string(self, start: int, line: int, col: int, prev: Token) -> Token:
        """Read a string token from the source file."""
        source = self.source
        body = source.body
        body_length = len(body)
        position = start + 1
        chunk_start = position
        value: List[str] = []
        append = value.append

        while position < body_length:
            char = body[position]
            if char in "\n\r":
                break
            if char == '"':
                append(body[chunk_start:position])
                return Token(
                    TokenKind.STRING,
                    start,
                    position + 1,
                    line,
                    col,
                    prev,
                    "".join(value),
                )
            if char < " " and char != "\t":
                raise GraphQLSyntaxError(
                    source,
                    position,
                    f"Invalid character within String: {print_char(char)}.",
                )
            position += 1
            if char == "\\":
                append(body[chunk_start : position - 1])
                char = body[position : position + 1]
                escaped = _ESCAPED_CHARS.get(char)
                if escaped:
                    value.append(escaped)
                elif char == "u" and position + 4 < body_length:
                    code = uni_char_code(*body[position + 1 : position + 5])
                    if code < 0:
                        escape = repr(body[position : position + 5])
                        escape = escape[:1] + "\\" + escape[1:]
                        raise GraphQLSyntaxError(
                            source,
                            position,
                            f"Invalid character escape sequence: {escape}.",
                        )
                    append(chr(code))
                    position += 4
                else:
                    escape = repr(char)
                    escape = escape[:1] + "\\" + escape[1:]
                    raise GraphQLSyntaxError(
                        source,
                        position,
                        f"Invalid character escape sequence: {escape}.",
                    )
                position += 1
                chunk_start = position

        raise GraphQLSyntaxError(source, position, "Unterminated string.")
Read a string token from the source file.