private Token parseNumber() {
        int start = position;
        int currentLine = line;
        int currentColumn = column;

        int startPosition = position;
        char current = peek();

        if (current == '-') {
            skip();
            if (!isDigit(peek())) {
                throw syntax(createInvalidNumberString(startPosition, "'-' must be followed by a digit"));
            }
        }

        consumeUntilNoLongerMatches(Lexer::isDigit);

        // Consume decimals.
        char peek = peek();
        if (peek == '.') {
            skip();
            if (consumeUntilNoLongerMatches(Lexer::isDigit) == 0) {
                throw syntax(createInvalidNumberString(startPosition, "'.' must be followed by a digit"));
            }
        }

        // Consume scientific notation.
        peek = peek();
        if (peek == 'e' || peek == 'E') {
            skip();
            peek = peek();
            if (peek == '+' || peek == '-') {
                skip();
            }
            if (consumeUntilNoLongerMatches(Lexer::isDigit) == 0) {
                throw syntax(createInvalidNumberString(startPosition, "'e', '+', and '-' must be followed by a digit"));
            }
        }

        String lexeme = sliceFrom(start);

        try {
            double number = Double.parseDouble(lexeme);
            LiteralExpression node = new LiteralExpression(number, currentLine, currentColumn);
            return new Token(TokenType.NUMBER, node, currentLine, currentColumn);
        } catch (NumberFormatException e) {
            throw syntax("Invalid number syntax: " + lexeme);
        }
    }
Gets a slice of the expression starting from the given 0-based
character position, read all the way through to the current
position of the parser.

@param start Position to slice from, ending at the current position.
@return Returns the slice of the expression from {@code start} to {@link #position}.
smithy-jmespath/src/main/java/software/amazon/smithy/jmespath/Lexer.java