167c3a3e4Sopenharmony_ci// (C) Copyright 2016 Jethro G. Beekman 267c3a3e4Sopenharmony_ci// 367c3a3e4Sopenharmony_ci// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 467c3a3e4Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 567c3a3e4Sopenharmony_ci// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 667c3a3e4Sopenharmony_ci// option. This file may not be copied, modified, or distributed 767c3a3e4Sopenharmony_ci// except according to those terms. 867c3a3e4Sopenharmony_ci//! Parsing C literals from byte slices. 967c3a3e4Sopenharmony_ci//! 1067c3a3e4Sopenharmony_ci//! This will parse a representation of a C literal into a Rust type. 1167c3a3e4Sopenharmony_ci//! 1267c3a3e4Sopenharmony_ci//! # characters 1367c3a3e4Sopenharmony_ci//! Character literals are stored into the `CChar` type, which can hold values 1467c3a3e4Sopenharmony_ci//! that are not valid Unicode code points. ASCII characters are represented as 1567c3a3e4Sopenharmony_ci//! `char`, literal bytes with the high byte set are converted into the raw 1667c3a3e4Sopenharmony_ci//! representation. Escape sequences are supported. If hex and octal escapes 1767c3a3e4Sopenharmony_ci//! map to an ASCII character, that is used, otherwise, the raw encoding is 1867c3a3e4Sopenharmony_ci//! used, including for values over 255. Unicode escapes are checked for 1967c3a3e4Sopenharmony_ci//! validity and mapped to `char`. Character sequences are not supported. Width 2067c3a3e4Sopenharmony_ci//! prefixes are ignored. 2167c3a3e4Sopenharmony_ci//! 2267c3a3e4Sopenharmony_ci//! # strings 2367c3a3e4Sopenharmony_ci//! Strings are interpreted as byte vectors. Escape sequences are supported. If 2467c3a3e4Sopenharmony_ci//! hex and octal escapes map onto multi-byte characters, they are truncated to 2567c3a3e4Sopenharmony_ci//! one 8-bit character. Unicode escapes are converted into their UTF-8 2667c3a3e4Sopenharmony_ci//! encoding. Width prefixes are ignored. 2767c3a3e4Sopenharmony_ci//! 2867c3a3e4Sopenharmony_ci//! # integers 2967c3a3e4Sopenharmony_ci//! Integers are read into `i64`. Binary, octal, decimal and hexadecimal are 3067c3a3e4Sopenharmony_ci//! all supported. If the literal value is between `i64::MAX` and `u64::MAX`, 3167c3a3e4Sopenharmony_ci//! it is bit-cast to `i64`. Values over `u64::MAX` cannot be parsed. Width and 3267c3a3e4Sopenharmony_ci//! sign suffixes are ignored. Sign prefixes are not supported. 3367c3a3e4Sopenharmony_ci//! 3467c3a3e4Sopenharmony_ci//! # real numbers 3567c3a3e4Sopenharmony_ci//! Reals are read into `f64`. Width suffixes are ignored. Sign prefixes are 3667c3a3e4Sopenharmony_ci//! not supported in the significand. Hexadecimal floating points are not 3767c3a3e4Sopenharmony_ci//! supported. 3867c3a3e4Sopenharmony_ci 3967c3a3e4Sopenharmony_ciuse std::char; 4067c3a3e4Sopenharmony_ciuse std::str::{self, FromStr}; 4167c3a3e4Sopenharmony_ci 4267c3a3e4Sopenharmony_ciuse nom::branch::alt; 4367c3a3e4Sopenharmony_ciuse nom::bytes::complete::is_not; 4467c3a3e4Sopenharmony_ciuse nom::bytes::complete::tag; 4567c3a3e4Sopenharmony_ciuse nom::character::complete::{char, one_of}; 4667c3a3e4Sopenharmony_ciuse nom::combinator::{complete, map, map_opt, opt, recognize}; 4767c3a3e4Sopenharmony_ciuse nom::multi::{fold_many0, many0, many1, many_m_n}; 4867c3a3e4Sopenharmony_ciuse nom::sequence::{delimited, pair, preceded, terminated, tuple}; 4967c3a3e4Sopenharmony_ciuse nom::*; 5067c3a3e4Sopenharmony_ci 5167c3a3e4Sopenharmony_ciuse crate::expr::EvalResult; 5267c3a3e4Sopenharmony_ciuse crate::ToCexprResult; 5367c3a3e4Sopenharmony_ci 5467c3a3e4Sopenharmony_ci#[derive(Debug, Copy, Clone, PartialEq, Eq)] 5567c3a3e4Sopenharmony_ci/// Representation of a C character 5667c3a3e4Sopenharmony_cipub enum CChar { 5767c3a3e4Sopenharmony_ci /// A character that can be represented as a `char` 5867c3a3e4Sopenharmony_ci Char(char), 5967c3a3e4Sopenharmony_ci /// Any other character (8-bit characters, unicode surrogates, etc.) 6067c3a3e4Sopenharmony_ci Raw(u64), 6167c3a3e4Sopenharmony_ci} 6267c3a3e4Sopenharmony_ci 6367c3a3e4Sopenharmony_ciimpl From<u8> for CChar { 6467c3a3e4Sopenharmony_ci fn from(i: u8) -> CChar { 6567c3a3e4Sopenharmony_ci match i { 6667c3a3e4Sopenharmony_ci 0..=0x7f => CChar::Char(i as u8 as char), 6767c3a3e4Sopenharmony_ci _ => CChar::Raw(i as u64), 6867c3a3e4Sopenharmony_ci } 6967c3a3e4Sopenharmony_ci } 7067c3a3e4Sopenharmony_ci} 7167c3a3e4Sopenharmony_ci 7267c3a3e4Sopenharmony_ci// A non-allocating version of this would be nice... 7367c3a3e4Sopenharmony_ciimpl std::convert::Into<Vec<u8>> for CChar { 7467c3a3e4Sopenharmony_ci fn into(self) -> Vec<u8> { 7567c3a3e4Sopenharmony_ci match self { 7667c3a3e4Sopenharmony_ci CChar::Char(c) => { 7767c3a3e4Sopenharmony_ci let mut s = String::with_capacity(4); 7867c3a3e4Sopenharmony_ci s.extend(&[c]); 7967c3a3e4Sopenharmony_ci s.into_bytes() 8067c3a3e4Sopenharmony_ci } 8167c3a3e4Sopenharmony_ci CChar::Raw(i) => { 8267c3a3e4Sopenharmony_ci let mut v = Vec::with_capacity(1); 8367c3a3e4Sopenharmony_ci v.push(i as u8); 8467c3a3e4Sopenharmony_ci v 8567c3a3e4Sopenharmony_ci } 8667c3a3e4Sopenharmony_ci } 8767c3a3e4Sopenharmony_ci } 8867c3a3e4Sopenharmony_ci} 8967c3a3e4Sopenharmony_ci 9067c3a3e4Sopenharmony_ci/// ensures the child parser consumes the whole input 9167c3a3e4Sopenharmony_cipub fn full<I: Clone, O, F>( 9267c3a3e4Sopenharmony_ci f: F, 9367c3a3e4Sopenharmony_ci) -> impl Fn(I) -> nom::IResult<I, O> 9467c3a3e4Sopenharmony_ciwhere 9567c3a3e4Sopenharmony_ci I: nom::InputLength, 9667c3a3e4Sopenharmony_ci F: Fn(I) -> nom::IResult<I, O>, 9767c3a3e4Sopenharmony_ci{ 9867c3a3e4Sopenharmony_ci move |input| { 9967c3a3e4Sopenharmony_ci let res = f(input); 10067c3a3e4Sopenharmony_ci match res { 10167c3a3e4Sopenharmony_ci Ok((i, o)) => { 10267c3a3e4Sopenharmony_ci if i.input_len() == 0 { 10367c3a3e4Sopenharmony_ci Ok((i, o)) 10467c3a3e4Sopenharmony_ci } else { 10567c3a3e4Sopenharmony_ci Err(nom::Err::Error(nom::error::Error::new(i, nom::error::ErrorKind::Complete))) 10667c3a3e4Sopenharmony_ci } 10767c3a3e4Sopenharmony_ci } 10867c3a3e4Sopenharmony_ci r => r, 10967c3a3e4Sopenharmony_ci } 11067c3a3e4Sopenharmony_ci } 11167c3a3e4Sopenharmony_ci} 11267c3a3e4Sopenharmony_ci 11367c3a3e4Sopenharmony_ci// ================================= 11467c3a3e4Sopenharmony_ci// ======== matching digits ======== 11567c3a3e4Sopenharmony_ci// ================================= 11667c3a3e4Sopenharmony_ci 11767c3a3e4Sopenharmony_cimacro_rules! byte { 11867c3a3e4Sopenharmony_ci ($($p: pat)|* ) => {{ 11967c3a3e4Sopenharmony_ci fn parser(i: &[u8]) -> crate::nom::IResult<&[u8], u8> { 12067c3a3e4Sopenharmony_ci match i.split_first() { 12167c3a3e4Sopenharmony_ci $(Some((&c @ $p,rest)))|* => Ok((rest,c)), 12267c3a3e4Sopenharmony_ci Some(_) => Err(nom::Err::Error(nom::error::Error::new(i, nom::error::ErrorKind::OneOf))), 12367c3a3e4Sopenharmony_ci None => Err(nom::Err::Incomplete(Needed::new(1))), 12467c3a3e4Sopenharmony_ci } 12567c3a3e4Sopenharmony_ci } 12667c3a3e4Sopenharmony_ci 12767c3a3e4Sopenharmony_ci parser 12867c3a3e4Sopenharmony_ci }} 12967c3a3e4Sopenharmony_ci} 13067c3a3e4Sopenharmony_ci 13167c3a3e4Sopenharmony_cifn binary(i: &[u8]) -> nom::IResult<&[u8], u8> { 13267c3a3e4Sopenharmony_ci byte!(b'0'..=b'1')(i) 13367c3a3e4Sopenharmony_ci} 13467c3a3e4Sopenharmony_ci 13567c3a3e4Sopenharmony_cifn octal(i: &[u8]) -> nom::IResult<&[u8], u8> { 13667c3a3e4Sopenharmony_ci byte!(b'0'..=b'7')(i) 13767c3a3e4Sopenharmony_ci} 13867c3a3e4Sopenharmony_ci 13967c3a3e4Sopenharmony_cifn decimal(i: &[u8]) -> nom::IResult<&[u8], u8> { 14067c3a3e4Sopenharmony_ci byte!(b'0'..=b'9')(i) 14167c3a3e4Sopenharmony_ci} 14267c3a3e4Sopenharmony_ci 14367c3a3e4Sopenharmony_cifn hexadecimal(i: &[u8]) -> nom::IResult<&[u8], u8> { 14467c3a3e4Sopenharmony_ci byte!(b'0' ..= b'9' | b'a' ..= b'f' | b'A' ..= b'F')(i) 14567c3a3e4Sopenharmony_ci} 14667c3a3e4Sopenharmony_ci 14767c3a3e4Sopenharmony_ci// ======================================== 14867c3a3e4Sopenharmony_ci// ======== characters and strings ======== 14967c3a3e4Sopenharmony_ci// ======================================== 15067c3a3e4Sopenharmony_ci 15167c3a3e4Sopenharmony_cifn escape2char(c: char) -> CChar { 15267c3a3e4Sopenharmony_ci CChar::Char(match c { 15367c3a3e4Sopenharmony_ci 'a' => '\x07', 15467c3a3e4Sopenharmony_ci 'b' => '\x08', 15567c3a3e4Sopenharmony_ci 'f' => '\x0c', 15667c3a3e4Sopenharmony_ci 'n' => '\n', 15767c3a3e4Sopenharmony_ci 'r' => '\r', 15867c3a3e4Sopenharmony_ci 't' => '\t', 15967c3a3e4Sopenharmony_ci 'v' => '\x0b', 16067c3a3e4Sopenharmony_ci _ => unreachable!("invalid escape {}", c), 16167c3a3e4Sopenharmony_ci }) 16267c3a3e4Sopenharmony_ci} 16367c3a3e4Sopenharmony_ci 16467c3a3e4Sopenharmony_cifn c_raw_escape(n: Vec<u8>, radix: u32) -> Option<CChar> { 16567c3a3e4Sopenharmony_ci str::from_utf8(&n) 16667c3a3e4Sopenharmony_ci .ok() 16767c3a3e4Sopenharmony_ci .and_then(|i| u64::from_str_radix(i, radix).ok()) 16867c3a3e4Sopenharmony_ci .map(|i| match i { 16967c3a3e4Sopenharmony_ci 0..=0x7f => CChar::Char(i as u8 as char), 17067c3a3e4Sopenharmony_ci _ => CChar::Raw(i), 17167c3a3e4Sopenharmony_ci }) 17267c3a3e4Sopenharmony_ci} 17367c3a3e4Sopenharmony_ci 17467c3a3e4Sopenharmony_cifn c_unicode_escape(n: Vec<u8>) -> Option<CChar> { 17567c3a3e4Sopenharmony_ci str::from_utf8(&n) 17667c3a3e4Sopenharmony_ci .ok() 17767c3a3e4Sopenharmony_ci .and_then(|i| u32::from_str_radix(i, 16).ok()) 17867c3a3e4Sopenharmony_ci .and_then(char::from_u32) 17967c3a3e4Sopenharmony_ci .map(CChar::Char) 18067c3a3e4Sopenharmony_ci} 18167c3a3e4Sopenharmony_ci 18267c3a3e4Sopenharmony_cifn escaped_char(i: &[u8]) -> nom::IResult<&[u8], CChar> { 18367c3a3e4Sopenharmony_ci preceded( 18467c3a3e4Sopenharmony_ci char('\\'), 18567c3a3e4Sopenharmony_ci alt(( 18667c3a3e4Sopenharmony_ci map(one_of(r#"'"?\"#), CChar::Char), 18767c3a3e4Sopenharmony_ci map(one_of("abfnrtv"), escape2char), 18867c3a3e4Sopenharmony_ci map_opt(many_m_n(1, 3, octal), |v| c_raw_escape(v, 8)), 18967c3a3e4Sopenharmony_ci map_opt(preceded(char('x'), many1(hexadecimal)), |v| { 19067c3a3e4Sopenharmony_ci c_raw_escape(v, 16) 19167c3a3e4Sopenharmony_ci }), 19267c3a3e4Sopenharmony_ci map_opt( 19367c3a3e4Sopenharmony_ci preceded(char('u'), many_m_n(4, 4, hexadecimal)), 19467c3a3e4Sopenharmony_ci c_unicode_escape, 19567c3a3e4Sopenharmony_ci ), 19667c3a3e4Sopenharmony_ci map_opt( 19767c3a3e4Sopenharmony_ci preceded(char('U'), many_m_n(8, 8, hexadecimal)), 19867c3a3e4Sopenharmony_ci c_unicode_escape, 19967c3a3e4Sopenharmony_ci ), 20067c3a3e4Sopenharmony_ci )), 20167c3a3e4Sopenharmony_ci )(i) 20267c3a3e4Sopenharmony_ci} 20367c3a3e4Sopenharmony_ci 20467c3a3e4Sopenharmony_cifn c_width_prefix(i: &[u8]) -> nom::IResult<&[u8], &[u8]> { 20567c3a3e4Sopenharmony_ci alt((tag("u8"), tag("u"), tag("U"), tag("L")))(i) 20667c3a3e4Sopenharmony_ci} 20767c3a3e4Sopenharmony_ci 20867c3a3e4Sopenharmony_cifn c_char(i: &[u8]) -> nom::IResult<&[u8], CChar> { 20967c3a3e4Sopenharmony_ci delimited( 21067c3a3e4Sopenharmony_ci terminated(opt(c_width_prefix), char('\'')), 21167c3a3e4Sopenharmony_ci alt(( 21267c3a3e4Sopenharmony_ci escaped_char, 21367c3a3e4Sopenharmony_ci map(byte!(0 ..= 91 /* \=92 */ | 93 ..= 255), CChar::from), 21467c3a3e4Sopenharmony_ci )), 21567c3a3e4Sopenharmony_ci char('\''), 21667c3a3e4Sopenharmony_ci )(i) 21767c3a3e4Sopenharmony_ci} 21867c3a3e4Sopenharmony_ci 21967c3a3e4Sopenharmony_cifn c_string(i: &[u8]) -> nom::IResult<&[u8], Vec<u8>> { 22067c3a3e4Sopenharmony_ci delimited( 22167c3a3e4Sopenharmony_ci alt((preceded(c_width_prefix, char('"')), char('"'))), 22267c3a3e4Sopenharmony_ci fold_many0( 22367c3a3e4Sopenharmony_ci alt(( 22467c3a3e4Sopenharmony_ci map(escaped_char, |c: CChar| c.into()), 22567c3a3e4Sopenharmony_ci map(is_not([b'\\', b'"']), |c: &[u8]| c.into()), 22667c3a3e4Sopenharmony_ci )), 22767c3a3e4Sopenharmony_ci Vec::new, 22867c3a3e4Sopenharmony_ci |mut v: Vec<u8>, res: Vec<u8>| { 22967c3a3e4Sopenharmony_ci v.extend_from_slice(&res); 23067c3a3e4Sopenharmony_ci v 23167c3a3e4Sopenharmony_ci }, 23267c3a3e4Sopenharmony_ci ), 23367c3a3e4Sopenharmony_ci char('"'), 23467c3a3e4Sopenharmony_ci )(i) 23567c3a3e4Sopenharmony_ci} 23667c3a3e4Sopenharmony_ci 23767c3a3e4Sopenharmony_ci// ================================ 23867c3a3e4Sopenharmony_ci// ======== parse integers ======== 23967c3a3e4Sopenharmony_ci// ================================ 24067c3a3e4Sopenharmony_ci 24167c3a3e4Sopenharmony_cifn c_int_radix(n: Vec<u8>, radix: u32) -> Option<u64> { 24267c3a3e4Sopenharmony_ci str::from_utf8(&n) 24367c3a3e4Sopenharmony_ci .ok() 24467c3a3e4Sopenharmony_ci .and_then(|i| u64::from_str_radix(i, radix).ok()) 24567c3a3e4Sopenharmony_ci} 24667c3a3e4Sopenharmony_ci 24767c3a3e4Sopenharmony_cifn take_ul(input: &[u8]) -> IResult<&[u8], &[u8]> { 24867c3a3e4Sopenharmony_ci let r = input.split_at_position(|c| c != b'u' && c != b'U' && c != b'l' && c != b'L'); 24967c3a3e4Sopenharmony_ci match r { 25067c3a3e4Sopenharmony_ci Err(Err::Incomplete(_)) => Ok((&input[input.len()..], input)), 25167c3a3e4Sopenharmony_ci res => res, 25267c3a3e4Sopenharmony_ci } 25367c3a3e4Sopenharmony_ci} 25467c3a3e4Sopenharmony_ci 25567c3a3e4Sopenharmony_cifn c_int(i: &[u8]) -> nom::IResult<&[u8], i64> { 25667c3a3e4Sopenharmony_ci map( 25767c3a3e4Sopenharmony_ci terminated( 25867c3a3e4Sopenharmony_ci alt(( 25967c3a3e4Sopenharmony_ci map_opt(preceded(tag("0x"), many1(complete(hexadecimal))), |v| { 26067c3a3e4Sopenharmony_ci c_int_radix(v, 16) 26167c3a3e4Sopenharmony_ci }), 26267c3a3e4Sopenharmony_ci map_opt(preceded(tag("0X"), many1(complete(hexadecimal))), |v| { 26367c3a3e4Sopenharmony_ci c_int_radix(v, 16) 26467c3a3e4Sopenharmony_ci }), 26567c3a3e4Sopenharmony_ci map_opt(preceded(tag("0b"), many1(complete(binary))), |v| { 26667c3a3e4Sopenharmony_ci c_int_radix(v, 2) 26767c3a3e4Sopenharmony_ci }), 26867c3a3e4Sopenharmony_ci map_opt(preceded(tag("0B"), many1(complete(binary))), |v| { 26967c3a3e4Sopenharmony_ci c_int_radix(v, 2) 27067c3a3e4Sopenharmony_ci }), 27167c3a3e4Sopenharmony_ci map_opt(preceded(char('0'), many1(complete(octal))), |v| { 27267c3a3e4Sopenharmony_ci c_int_radix(v, 8) 27367c3a3e4Sopenharmony_ci }), 27467c3a3e4Sopenharmony_ci map_opt(many1(complete(decimal)), |v| c_int_radix(v, 10)), 27567c3a3e4Sopenharmony_ci |input| Err(crate::nom::Err::Error(nom::error::Error::new(input, crate::nom::ErrorKind::Fix))), 27667c3a3e4Sopenharmony_ci )), 27767c3a3e4Sopenharmony_ci opt(take_ul), 27867c3a3e4Sopenharmony_ci ), 27967c3a3e4Sopenharmony_ci |i| i as i64, 28067c3a3e4Sopenharmony_ci )(i) 28167c3a3e4Sopenharmony_ci} 28267c3a3e4Sopenharmony_ci 28367c3a3e4Sopenharmony_ci// ============================== 28467c3a3e4Sopenharmony_ci// ======== parse floats ======== 28567c3a3e4Sopenharmony_ci// ============================== 28667c3a3e4Sopenharmony_ci 28767c3a3e4Sopenharmony_cifn float_width(i: &[u8]) -> nom::IResult<&[u8], u8> { 28867c3a3e4Sopenharmony_ci nom::combinator::complete(byte!(b'f' | b'l' | b'F' | b'L'))(i) 28967c3a3e4Sopenharmony_ci} 29067c3a3e4Sopenharmony_ci 29167c3a3e4Sopenharmony_cifn float_exp(i: &[u8]) -> nom::IResult<&[u8], (Option<u8>, Vec<u8>)> { 29267c3a3e4Sopenharmony_ci preceded( 29367c3a3e4Sopenharmony_ci byte!(b'e' | b'E'), 29467c3a3e4Sopenharmony_ci pair(opt(byte!(b'-' | b'+')), many1(complete(decimal))), 29567c3a3e4Sopenharmony_ci )(i) 29667c3a3e4Sopenharmony_ci} 29767c3a3e4Sopenharmony_ci 29867c3a3e4Sopenharmony_cifn c_float(i: &[u8]) -> nom::IResult<&[u8], f64> { 29967c3a3e4Sopenharmony_ci map_opt( 30067c3a3e4Sopenharmony_ci alt(( 30167c3a3e4Sopenharmony_ci terminated( 30267c3a3e4Sopenharmony_ci recognize(tuple(( 30367c3a3e4Sopenharmony_ci many1(complete(decimal)), 30467c3a3e4Sopenharmony_ci byte!(b'.'), 30567c3a3e4Sopenharmony_ci many0(complete(decimal)), 30667c3a3e4Sopenharmony_ci ))), 30767c3a3e4Sopenharmony_ci opt(float_width), 30867c3a3e4Sopenharmony_ci ), 30967c3a3e4Sopenharmony_ci terminated( 31067c3a3e4Sopenharmony_ci recognize(tuple(( 31167c3a3e4Sopenharmony_ci many0(complete(decimal)), 31267c3a3e4Sopenharmony_ci byte!(b'.'), 31367c3a3e4Sopenharmony_ci many1(complete(decimal)), 31467c3a3e4Sopenharmony_ci ))), 31567c3a3e4Sopenharmony_ci opt(float_width), 31667c3a3e4Sopenharmony_ci ), 31767c3a3e4Sopenharmony_ci terminated( 31867c3a3e4Sopenharmony_ci recognize(tuple(( 31967c3a3e4Sopenharmony_ci many0(complete(decimal)), 32067c3a3e4Sopenharmony_ci opt(byte!(b'.')), 32167c3a3e4Sopenharmony_ci many1(complete(decimal)), 32267c3a3e4Sopenharmony_ci float_exp, 32367c3a3e4Sopenharmony_ci ))), 32467c3a3e4Sopenharmony_ci opt(float_width), 32567c3a3e4Sopenharmony_ci ), 32667c3a3e4Sopenharmony_ci terminated( 32767c3a3e4Sopenharmony_ci recognize(tuple(( 32867c3a3e4Sopenharmony_ci many1(complete(decimal)), 32967c3a3e4Sopenharmony_ci opt(byte!(b'.')), 33067c3a3e4Sopenharmony_ci many0(complete(decimal)), 33167c3a3e4Sopenharmony_ci float_exp, 33267c3a3e4Sopenharmony_ci ))), 33367c3a3e4Sopenharmony_ci opt(float_width), 33467c3a3e4Sopenharmony_ci ), 33567c3a3e4Sopenharmony_ci terminated(recognize(many1(complete(decimal))), float_width), 33667c3a3e4Sopenharmony_ci )), 33767c3a3e4Sopenharmony_ci |v| str::from_utf8(v).ok().and_then(|i| f64::from_str(i).ok()), 33867c3a3e4Sopenharmony_ci )(i) 33967c3a3e4Sopenharmony_ci} 34067c3a3e4Sopenharmony_ci 34167c3a3e4Sopenharmony_ci// ================================ 34267c3a3e4Sopenharmony_ci// ======== main interface ======== 34367c3a3e4Sopenharmony_ci// ================================ 34467c3a3e4Sopenharmony_ci 34567c3a3e4Sopenharmony_cifn one_literal(input: &[u8]) -> nom::IResult<&[u8], EvalResult, crate::Error<&[u8]>> { 34667c3a3e4Sopenharmony_ci alt(( 34767c3a3e4Sopenharmony_ci map(full(c_char), EvalResult::Char), 34867c3a3e4Sopenharmony_ci map(full(c_int), |i| EvalResult::Int(::std::num::Wrapping(i))), 34967c3a3e4Sopenharmony_ci map(full(c_float), EvalResult::Float), 35067c3a3e4Sopenharmony_ci map(full(c_string), EvalResult::Str), 35167c3a3e4Sopenharmony_ci ))(input) 35267c3a3e4Sopenharmony_ci .to_cexpr_result() 35367c3a3e4Sopenharmony_ci} 35467c3a3e4Sopenharmony_ci 35567c3a3e4Sopenharmony_ci/// Parse a C literal. 35667c3a3e4Sopenharmony_ci/// 35767c3a3e4Sopenharmony_ci/// The input must contain exactly the representation of a single literal 35867c3a3e4Sopenharmony_ci/// token, and in particular no whitespace or sign prefixes. 35967c3a3e4Sopenharmony_cipub fn parse(input: &[u8]) -> IResult<&[u8], EvalResult, crate::Error<&[u8]>> { 36067c3a3e4Sopenharmony_ci crate::assert_full_parse(one_literal(input)) 36167c3a3e4Sopenharmony_ci} 362