fn scan_number_literal(&mut self) -> Result<Lit, ()> {
        // First: lex the whole number part (maybe the only part)
        let (r, s) = match self.curr {
            // if literal is starting with '0' (-> not decimal or single digit)
            Some('0') => {
                match self.peek.unwrap_or('\0') {
                    // hexadecimal literal
                    'x' | 'X' => {
                        self.dbump();   // skip "0x"
                        (16, if self.curr != Some('.') {
                            // will never contain a Report with radix 16
                            try!(self.scan_digits(16))
                        } else {
                            "".into()
                        })
                    },
                    // binary literal
                    'b' | 'B' => {
                        self.dbump();   // skip "0b"
                        (2, try!(self.scan_digits(2)))
                    },
                    // octal literal
                    '0' ... '9' => {
                        self.bump();   // skip "0"
                        (8, try!(self.scan_digits(8)))
                    },
                    // just a '0'
                    _ => {
                        self.bump();
                        (10, "0".into())
                    }
                }
            },
            // literal starting with a dot: decimal float. Note: No bump
            Some('.') => (10, "".into()),
            // literal starting with non-null digit (-> decimal)
            // will never contain a Report with radix 10
            _ => (10, try!(self.scan_digits(10)))
        };

        // look at the first char after the whole number part
        match self.curr.unwrap_or('\0') {
            'l' | 'L' => {
                self.bump();
                Ok(Lit::Integer { raw: s, is_long: true, radix: r as u8 })
            },
            // After a whole number part may follow a float type suffix
            c @ 'f' | c @ 'F' | c @ 'd' | c @ 'D' if !s.is_empty() => {
                self.bump();
                Ok(Lit::Float {
                    raw: s,
                    is_double: (c != 'f' && c != 'F'),
                    radix: r as u8,
                    exp: "".into(),
                })
            },
            // If we have a whole number part, there may follow an exponent part
            'p' | 'P' | 'e' | 'E' if !s.is_empty() => {
                match self.scan_float_exp(r == 16) {
                    // Failing to scan the exponent means that the exponent
                    // char is wrong (p for hex, e for decimal)
                    None => {
                        Err(if r == 16 {
                            self.simple_error((), "invalid exponent indicator \
                                for hex float literal (use 'p' or 'P' instead")
                        } else {
                            self.simple_error((), "invalid exponent indicator \
                                for decimal float literal (use 'e' or 'E' \
                                instead)")
                        })
                    },
                    Some(ex) => {
                        // A float type suffix may follow
                        let double = self.scan_double_suffix().unwrap_or(true);

                        Ok(Lit::Float {
                            raw: s,
                            is_double: double,
                            radix: r as u8,
                            exp: ex,
                        })
                    }
                }
            }

            // A dot means float literal and may occur in two situations:
            // - we already read a whole number part
            // - the dot was the start of the literal
            '.' => {
                // make sure the literal is in the right base
                if r != 10 && r != 16 {
                    return Err(self.simple_error((), format!("float literals \
                        may only be expressed in decimal or hexadecimal, not \
                        base {}", r)));
                }
                self.bump();    // dot

                // We do not need to check if both, the whole number and
                // fraction part, are empty in decimal case for the
                // following reason:
                // The precondition tells us that this function is only
                // called if `curr` is a number OR a dot followed by a
                // number. This guarantees that at least one part is
                // non-empty in decimal case.
                let fraction = try!(self.scan_digits(r));
                if r == 16 && s.is_empty() && fraction.is_empty() {
                    return Err(self.simple_error((), "hex float literals need \
                        either a whole number or a fraction part"));
                }

                // In a hexadecimal float literal the exponent is required
                let exp = self.scan_float_exp(r == 16).unwrap_or("".into());
                if r == 16 && exp.is_empty() {
                    return Err(self.simple_error((), "hex float literals are \
                        required to have an exponent"));
                }

                // type suffix is always optional
                let is_double = self.scan_double_suffix().unwrap_or(true);
                Ok(Lit::Float {
                    raw: format!("{}.{}", s, fraction),
                    is_double: is_double,
                    radix: r as u8,
                    exp: exp,
                })
            },
            _ => Ok(Lit::Integer { raw: s, is_long: false, radix: r as u8 }),
        }
    }
/// Scans a Java number literal and returns it. The literal may be a float
/// or a integer literal. See section 3.10.1 and 3.10.2.
///
/// Parsing the string as a number could be done at this point in theory.
/// I need to think about it to find out if it makes sense.
///
/// ## Preconditions
/// `curr` needs to be in '0' ... '9' or a '.' followed by '0' ... '9'
Scans a Java number literal and returns it. The literal may be a float
or a integer literal.

Parsing the string as a number could be done at this point in theory.
I need to think about it to find out if it makes sense.
Scans a Java number literal and returns it . The literal may be a float or a integer literal . Parsing the string as a number could be done at this point in theory . I need to think about it to find out if it makes sense .
fn scan_number_literal(&mut self) -> Result<Lit, ()> {
        // First: lex the whole number part (maybe the only part)
        let (r, s) = match self.curr {
            // if literal is starting with '0' (-> not decimal or single digit)
            Some('0') => {
                match self.peek.unwrap_or('\0') {
                    // hexadecimal literal
                    'x' | 'X' => {
                        self.dbump();   // skip "0x"
                        (16, if self.curr != Some('.') {
                            // will never contain a Report with radix 16
                            try!(self.scan_digits(16))
                        } else {
                            "".into()
                        })
                    },
                    // binary literal
                    'b' | 'B' => {
                        self.dbump();   // skip "0b"
                        (2, try!(self.scan_digits(2)))
                    },
                    // octal literal
                    '0' ... '9' => {
                        self.bump();   // skip "0"
                        (8, try!(self.scan_digits(8)))
                    },
                    // just a '0'
                    _ => {
                        self.bump();
                        (10, "0".into())
                    }
                }
            },
            // literal starting with a dot: decimal float. Note: No bump
            Some('.') => (10, "".into()),
            // literal starting with non-null digit (-> decimal)
            // will never contain a Report with radix 10
            _ => (10, try!(self.scan_digits(10)))
        };
        // look at the first char after the whole number part
        match self.curr.unwrap_or('\0') {
            'l' | 'L' => {
                self.bump();
                Ok(Lit::Integer { raw: s, is_long: true, radix: r as u8 })
            },
            // After a whole number part may follow a float type suffix
            c @ 'f' | c @ 'F' | c @ 'd' | c @ 'D' if !s.is_empty() => {
                self.bump();
                Ok(Lit::Float {
                    raw: s,
                    is_double: (c != 'f' && c != 'F'),
                    radix: r as u8,
                    exp: "".into(),
                })
            },
            // If we have a whole number part, there may follow an exponent part
            'p' | 'P' | 'e' | 'E' if !s.is_empty() => {
                match self.scan_float_exp(r == 16) {
                    // Failing to scan the exponent means that the exponent
                    // char is wrong (p for hex, e for decimal)
                    None => {
                        Err(if r == 16 {
                            self.simple_error((), "invalid exponent indicator \
                                for hex float literal (use 'p' or 'P' instead")
                        } else {
                            self.simple_error((), "invalid exponent indicator \
                                for decimal float literal (use 'e' or 'E' \
                                instead)")
                        })
                    },
                    Some(ex) => {
                        // A float type suffix may follow
                        let double = self.scan_double_suffix().unwrap_or(true);
                        Ok(Lit::Float {
                            raw: s,
                            is_double: double,
                            radix: r as u8,
                            exp: ex,
                        })
                    }
                }
            }
            // A dot means float literal and may occur in two situations:
            // - we already read a whole number part
            // - the dot was the start of the literal
            '.' => {
                // make sure the literal is in the right base
                if r != 10 && r != 16 {
                    return Err(self.simple_error((), format!("float literals \
                        may only be expressed in decimal or hexadecimal, not \
                        base {}", r)));
                }
                self.bump();    // dot
                // We do not need to check if both, the whole number and
                // fraction part, are empty in decimal case for the
                // following reason:
                // The precondition tells us that this function is only
                // called if `curr` is a number OR a dot followed by a
                // number. This guarantees that at least one part is
                // non-empty in decimal case.
                let fraction = try!(self.scan_digits(r));
                if r == 16 && s.is_empty() && fraction.is_empty() {
                    return Err(self.simple_error((), "hex float literals need \
                        either a whole number or a fraction part"));
                }
                // In a hexadecimal float literal the exponent is required
                let exp = self.scan_float_exp(r == 16).unwrap_or("".into());
                if r == 16 && exp.is_empty() {
                    return Err(self.simple_error((), "hex float literals are \
                        required to have an exponent"));
                }
                // type suffix is always optional
                let is_double = self.scan_double_suffix().unwrap_or(true);
                Ok(Lit::Float {
                    raw: format!("{}.{}", s, fraction),
                    is_double: is_double,
                    radix: r as u8,
                    exp: exp,
                })
            },
            _ => Ok(Lit::Integer { raw: s, is_long: false, radix: r as u8 }),
        }
    }
fn scan_number_literal ( & mut self ) -> Result < Lit , ( ) > { // First: lex the whole number part (maybe the only part) let ( r , s ) = match self . curr { // if literal is starting with '0' (-> not decimal or single digit) Some ( '0' ) => { match self . peek . unwrap_or ( '\0' ) { // hexadecimal literal 'x' | 'X' => { self . dbump ( ) ; // skip "0x" ( 16 , if self . curr != Some ( '.' ) { // will never contain a Report with radix 16 try ! ( self scan_digits ( 16 ) ) } else { " " . into ( ) } ) } , // binary literal 'b' | 'B' => { self . dbump ( ) ; // skip "0b" ( 2 , try ! ( self scan_digits ( 2 ) ) ) } , // octal literal '0' ... '9' => { self . bump ( ) ; // skip "0" ( 8 , try ! ( self scan_digits ( 8 ) ) ) } , // just a '0' _ => { self . bump ( ) ; ( 10 , " " . into ( ) ) } } } , // literal starting with a dot: decimal float. Note: No bump Some ( '.' ) => ( 10 , " " . into ( ) ) , // literal starting with non-null digit (-> decimal) // will never contain a Report with radix 10 _ => ( 10 , try ! ( self scan_digits ( 10 ) ) ) } ; // look at the first char after the whole number part match self . curr . unwrap_or ( '\0' ) { 'l' | 'L' => { self . bump ( ) ; Ok ( Lit :: Integer { raw : s , is_long : true , radix : r as u8 } ) } , // After a whole number part may follow a float type suffix c @ 'f' | c @ 'F' | c @ 'd' | c @ 'D' if ! s . is_empty ( ) => { self . bump ( ) ; Ok ( Lit :: Float { raw : s , is_double : ( c != 'f' && c != 'F' ) , radix : r as u8 , exp : " " . into ( ) , } ) } , // If we have a whole number part, there may follow an exponent part 'p' | 'P' | 'e' | 'E' if ! s . is_empty ( ) => { match self . scan_float_exp ( r == 16 ) { // Failing to scan the exponent means that the exponent // char is wrong (p for hex, e for decimal) None => { Err ( if r == 16 { self . simple_error ( ( ) , " \
 " ) } else { self . simple_error ( ( ) , " \
 \
 " ) } ) } , Some ( ex ) => { // A float type suffix may follow let double = self . scan_double_suffix ( ) . unwrap_or ( true ) ; Ok ( Lit :: Float { raw : s , is_double : double , radix : r as u8 , exp : ex , } ) } } } // A dot means float literal and may occur in two situations: // - we already read a whole number part // - the dot was the start of the literal '.' => { // make sure the literal is in the right base if r != 10 && r != 16 { return Err ( self . simple_error ( ( ) , format ! ( " \
 \
 " r ) ) ) ; } self . bump ( ) ; // dot // We do not need to check if both, the whole number and // fraction part, are empty in decimal case for the // following reason: // The precondition tells us that this function is only // called if `curr` is a number OR a dot followed by a // number. This guarantees that at least one part is // non-empty in decimal case. let fraction = try ! ( self scan_digits ( r ) ) ; if r == 16 && s . is_empty ( ) && fraction . is_empty ( ) { return Err ( self . simple_error ( ( ) , " \
 " ) ) ; } // In a hexadecimal float literal the exponent is required let exp = self . scan_float_exp ( r == 16 ) . unwrap_or ( " " . into ( ) ) ; if r == 16 && exp . is_empty ( ) { return Err ( self . simple_error ( ( ) , " \
 " ) ) ; } // type suffix is always optional let is_double = self . scan_double_suffix ( ) . unwrap_or ( true ) ; Ok ( Lit :: Float { raw : format ! ( " " s fraction ) , is_double : is_double , radix : r as u8 , exp : exp , } ) } , _ => Ok ( Lit :: Integer { raw : s , is_long : false , radix : r as u8 } ) , } }
Scans a Java number literal and returns it.
Scans a Java number literal and returns it .
&mut self
&mut self
preconditions
`curr` needs to be in '0' ...
` curr ` needs to be in ' 0 ' ...