2018 edition

This commit is contained in:
Jon Gjengset 2020-02-17 12:43:16 -05:00
parent 4a73811e9c
commit 3a323a4e41
No known key found for this signature in database
GPG Key ID: FAEA8B761ADA5F4C
6 changed files with 66 additions and 64 deletions

View File

@ -1,6 +1,7 @@
[package]
name = "cexpr"
version = "0.3.6"
edition = "2018"
authors = ["Jethro Beekman <jethro@jbeekman.nl>"]
license = "Apache-2.0/MIT"
description = "A C expression parser and evaluator"

1
rustfmt.toml Normal file
View File

@ -0,0 +1 @@
edition = "2018"

View File

@ -26,9 +26,9 @@ use std::ops::{
ShrAssign, SubAssign,
};
use literal::{self, CChar};
use nom_crate::*;
use token::{Kind as TokenKind, Token};
use crate::literal::{self, CChar};
use crate::nom_crate::*;
use crate::token::{Kind as TokenKind, Token};
/// Expression parser/evaluator that supports identifiers.
#[derive(Debug)]
@ -38,7 +38,7 @@ pub struct IdentifierParser<'ident> {
#[derive(Copy, Clone)]
struct PRef<'a>(&'a IdentifierParser<'a>);
pub type CResult<'a, R> = IResult<&'a [Token], R, ::Error>;
pub type CResult<'a, R> = IResult<&'a [Token], R, crate::Error>;
/// The result of parsing a literal or evaluating an expression.
#[derive(Debug, Clone, PartialEq)]
@ -90,13 +90,13 @@ impl From<Vec<u8>> for EvalResult {
macro_rules! exact_token (
($i:expr, $k:ident, $c:expr) => ({
if $i.is_empty() {
let res: CResult<&[u8]> = Err(::nom_crate::Err::Incomplete(Needed::Size($c.len())));
let res: CResult<'_, &[u8]> = Err(crate::nom_crate::Err::Incomplete(Needed::Size($c.len())));
res
} else {
if $i[0].kind==TokenKind::$k && &$i[0].raw[..]==$c {
Ok((&$i[1..], &$i[0].raw[..]))
} else {
Err(::nom_crate::Err::Error(error_position!($i, ErrorKind::Custom(::Error::ExactToken(TokenKind::$k,$c)))))
Err(crate::nom_crate::Err::Error(error_position!($i, ErrorKind::Custom(crate::Error::ExactToken(TokenKind::$k,$c)))))
}
}
});
@ -105,13 +105,13 @@ macro_rules! exact_token (
macro_rules! typed_token (
($i:expr, $k:ident) => ({
if $i.is_empty() {
let res: CResult<&[u8]> = Err(::nom_crate::Err::Incomplete(Needed::Size(1)));
let res: CResult<'_, &[u8]> = Err(crate::nom_crate::Err::Incomplete(Needed::Size(1)));
res
} else {
if $i[0].kind==TokenKind::$k {
Ok((&$i[1..], &$i[0].raw[..]))
} else {
Err(Err::Error(error_position!($i, ErrorKind::Custom(::Error::TypedToken(TokenKind::$k)))))
Err(Err::Error(error_position!($i, ErrorKind::Custom(crate::Error::TypedToken(TokenKind::$k)))))
}
}
});
@ -121,7 +121,7 @@ macro_rules! typed_token (
macro_rules! any_token (
($i:expr,) => ({
if $i.is_empty() {
let res: CResult<&Token> = Err(::nom_crate::Err::Incomplete(Needed::Size(1)));
let res: CResult<'_, &Token> = Err(::nom_crate::Err::Incomplete(Needed::Size(1)));
res
} else {
Ok((&$i[1..], &$i[0]))
@ -137,14 +137,14 @@ macro_rules! one_of_punctuation (
($i:expr, $c:expr) => ({
if $i.is_empty() {
let min = $c.iter().map(|opt|opt.len()).min().expect("at least one option");
let res: CResult<&[u8]> = Err(::nom_crate::Err::Incomplete(Needed::Size(min)));
let res: CResult<'_, &[u8]> = Err(crate::nom_crate::Err::Incomplete(Needed::Size(min)));
res
} else {
if $i[0].kind==TokenKind::Punctuation && $c.iter().any(|opt|opt.as_bytes()==&$i[0].raw[..]) {
Ok((&$i[1..], &$i[0].raw[..]))
} else {
const VALID_VALUES: &'static [&'static str] = &$c;
Err(Err::Error(error_position!($i, ErrorKind::Custom(::Error::ExactTokens(TokenKind::Punctuation,VALID_VALUES)))))
Err(Err::Error(error_position!($i, ErrorKind::Custom(crate::Error::ExactTokens(TokenKind::Punctuation,VALID_VALUES)))))
}
}
});
@ -155,13 +155,13 @@ macro_rules! one_of_punctuation (
macro_rules! comp (
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
use ::nom_crate::lib::std::result::Result::*;
use ::nom_crate::{Err,ErrorKind};
use crate::nom_crate::lib::std::result::Result::*;
use crate::nom_crate::{Err,ErrorKind};
let i_ = $i.clone();
match $submac!(i_, $($args)*) {
Err(Err::Incomplete(_)) => {
Err(Err::Error(error_position!($i, ErrorKind::Complete::<::Error>)))
Err(Err::Error(error_position!($i, ErrorKind::Complete::<crate::Error>)))
},
rest => rest
}
@ -303,7 +303,7 @@ macro_rules! numeric (
);
impl<'a> PRef<'a> {
method!(unary<PRef<'a>,&[Token],EvalResult,::Error>, mut self,
method!(unary<PRef<'a>,&[Token],EvalResult,crate::Error>, mut self,
alt!(
delimited!(p!("("),call_m!(self.numeric_expr),p!(")")) |
numeric!(call_m!(self.literal)) |
@ -312,7 +312,7 @@ impl<'a> PRef<'a> {
)
);
method!(mul_div_rem<PRef<'a>,&[Token],EvalResult,::Error>, mut self,
method!(mul_div_rem<PRef<'a>,&[Token],EvalResult,crate::Error>, mut self,
do_parse!(
acc: call_m!(self.unary) >>
res: fold_many0!(
@ -331,7 +331,7 @@ impl<'a> PRef<'a> {
)
);
method!(add_sub<PRef<'a>,&[Token],EvalResult,::Error>, mut self,
method!(add_sub<PRef<'a>,&[Token],EvalResult,crate::Error>, mut self,
do_parse!(
acc: call_m!(self.mul_div_rem) >>
res: fold_many0!(
@ -349,7 +349,7 @@ impl<'a> PRef<'a> {
)
);
method!(shl_shr<PRef<'a>,&[Token],EvalResult,::Error>, mut self,
method!(shl_shr<PRef<'a>,&[Token],EvalResult,crate::Error>, mut self,
numeric!(do_parse!(
acc: call_m!(self.add_sub) >>
res: fold_many0!(
@ -367,7 +367,7 @@ impl<'a> PRef<'a> {
))
);
method!(and<PRef<'a>,&[Token],EvalResult,::Error>, mut self,
method!(and<PRef<'a>,&[Token],EvalResult,crate::Error>, mut self,
numeric!(do_parse!(
acc: call_m!(self.shl_shr) >>
res: fold_many0!(
@ -381,7 +381,7 @@ impl<'a> PRef<'a> {
))
);
method!(xor<PRef<'a>,&[Token],EvalResult,::Error>, mut self,
method!(xor<PRef<'a>,&[Token],EvalResult,crate::Error>, mut self,
numeric!(do_parse!(
acc: call_m!(self.and) >>
res: fold_many0!(
@ -395,7 +395,7 @@ impl<'a> PRef<'a> {
))
);
method!(or<PRef<'a>,&[Token],EvalResult,::Error>, mut self,
method!(or<PRef<'a>,&[Token],EvalResult,crate::Error>, mut self,
numeric!(do_parse!(
acc: call_m!(self.xor) >>
res: fold_many0!(
@ -410,7 +410,7 @@ impl<'a> PRef<'a> {
);
#[inline(always)]
fn numeric_expr(self, input: &[Token]) -> (Self, CResult<EvalResult>) {
fn numeric_expr(self, input: &[Token]) -> (Self, CResult<'_, EvalResult>) {
self.or(input)
}
}
@ -420,7 +420,7 @@ impl<'a> PRef<'a> {
// =======================================================
impl<'a> PRef<'a> {
fn identifier(self, input: &[Token]) -> (Self, CResult<EvalResult>) {
fn identifier(self, input: &[Token]) -> (Self, CResult<'_, EvalResult>) {
(
self,
match input.split_first() {
@ -437,19 +437,19 @@ impl<'a> PRef<'a> {
} else {
Err(Err::Error(error_position!(
input,
ErrorKind::Custom(::Error::UnknownIdentifier)
ErrorKind::Custom(crate::Error::UnknownIdentifier)
)))
}
}
Some(_) => Err(Err::Error(error_position!(
input,
ErrorKind::Custom(::Error::TypedToken(TokenKind::Identifier))
ErrorKind::Custom(crate::Error::TypedToken(TokenKind::Identifier))
))),
},
)
}
fn literal(self, input: &[Token]) -> (Self, CResult<EvalResult>) {
fn literal(self, input: &[Token]) -> (Self, CResult<'_, EvalResult>) {
(
self,
match input.split_first() {
@ -464,18 +464,18 @@ impl<'a> PRef<'a> {
Ok((_, result)) => Ok((rest, result)),
_ => Err(Err::Error(error_position!(
input,
ErrorKind::Custom(::Error::InvalidLiteral)
ErrorKind::Custom(crate::Error::InvalidLiteral)
))),
},
Some(_) => Err(Err::Error(error_position!(
input,
ErrorKind::Custom(::Error::TypedToken(TokenKind::Literal))
ErrorKind::Custom(crate::Error::TypedToken(TokenKind::Literal))
))),
},
)
}
method!(string<PRef<'a>,&[Token],Vec<u8>,::Error>, mut self,
method!(string<PRef<'a>,&[Token],Vec<u8>,crate::Error>, mut self,
alt!(
map_opt!(call_m!(self.literal),EvalResult::as_str) |
map_opt!(call_m!(self.identifier),EvalResult::as_str)
@ -483,14 +483,14 @@ impl<'a> PRef<'a> {
);
// "string1" "string2" etc...
method!(concat_str<PRef<'a>,&[Token],EvalResult,::Error>, mut self,
method!(concat_str<PRef<'a>,&[Token],EvalResult,crate::Error>, mut self,
map!(
pair!(call_m!(self.string),many0!(comp!(call_m!(self.string)))),
|(first,v)| Vec::into_iter(v).fold(first,|mut s,elem|{Vec::extend_from_slice(&mut s,Vec::<u8>::as_slice(&elem));s}).into()
)
);
method!(expr<PRef<'a>,&[Token],EvalResult,::Error>, mut self,
method!(expr<PRef<'a>,&[Token],EvalResult,crate::Error>, mut self,
alt!(
call_m!(self.numeric_expr) |
delimited!(p!("("),call_m!(self.expr),p!(")")) |
@ -500,7 +500,7 @@ impl<'a> PRef<'a> {
)
);
method!(macro_definition<PRef<'a>,&[Token],(&[u8],EvalResult),::Error>, mut self,
method!(macro_definition<PRef<'a>,&[Token],(&[u8],EvalResult),crate::Error>, mut self,
pair!(typed_token!(Identifier),call_m!(self.expr))
);
}
@ -513,14 +513,14 @@ impl<'a> ::std::ops::Deref for PRef<'a> {
}
impl<'ident> IdentifierParser<'ident> {
fn as_ref(&self) -> PRef {
fn as_ref(&self) -> PRef<'_> {
PRef(self)
}
/// Create a new `IdentifierParser` with a set of known identifiers. When
/// a known identifier is encountered during parsing, it is substituted
/// for the value specified.
pub fn new(identifiers: &HashMap<Vec<u8>, EvalResult>) -> IdentifierParser {
pub fn new(identifiers: &HashMap<Vec<u8>, EvalResult>) -> IdentifierParser<'_> {
IdentifierParser {
identifiers: identifiers,
}
@ -555,7 +555,7 @@ impl<'ident> IdentifierParser<'ident> {
/// #define NEGATIVE_THREE(IDENTIFIER) -3
/// ```
pub fn macro_definition<'a>(&self, input: &'a [Token]) -> CResult<'a, (&'a [u8], EvalResult)> {
::assert_full_parse(self.as_ref().macro_definition(input).1)
crate::assert_full_parse(self.as_ref().macro_definition(input).1)
}
}
@ -619,7 +619,7 @@ named_attr!(
/// let (_, evaluated) = assert_full_parse(IdentifierParser::new(&idents).expr(expr)).unwrap();
/// assert_eq!(evaluated, EvalResult::Str(b"testsuffix".to_vec()));
/// ```
,pub fn_macro_declaration<&[Token],(&[u8],Vec<&[u8]>),::Error>,
,pub fn_macro_declaration<&[Token],(&[u8],Vec<&[u8]>),crate::Error>,
pair!(
typed_token!(Identifier),
delimited!(

View File

@ -5,19 +5,21 @@
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![warn(rust_2018_idioms)]
#![allow(deprecated)]
#[macro_use]
extern crate nom as nom_crate;
pub mod nom {
//! nom's result types, re-exported.
pub use nom_crate::{Err, ErrorKind, IResult, Needed};
pub use crate::nom_crate::{Err, ErrorKind, IResult, Needed};
}
pub mod expr;
pub mod literal;
pub mod token;
use nom::*;
use crate::nom::*;
#[derive(Debug)]
/// Parsing errors specific to C parsing
@ -51,18 +53,18 @@ macro_rules! identity (
/// If the input result indicates a succesful parse, but there is data left,
/// return an `Error::Partial` instead.
pub fn assert_full_parse<I, O, E>(result: IResult<&[I], O, E>) -> IResult<&[I], O, ::Error>
pub fn assert_full_parse<I, O, E>(result: IResult<&[I], O, E>) -> IResult<&[I], O, crate::Error>
where
Error: From<E>,
{
match fix_error!((), ::Error, identity!(result)) {
match fix_error!((), crate::Error, identity!(result)) {
Ok((rem, output)) => {
if rem.len() == 0 {
Ok((rem, output))
} else {
Err(Err::Error(error_position!(
rem,
ErrorKind::Custom(::Error::Partial)
ErrorKind::Custom(crate::Error::Partial)
)))
}
}

View File

@ -39,9 +39,9 @@
use std::char;
use std::str::{self, FromStr};
use nom_crate::*;
use crate::nom_crate::*;
use expr::EvalResult;
use crate::expr::EvalResult;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// Representation of a C character
@ -55,7 +55,7 @@ pub enum CChar {
impl From<u8> for CChar {
fn from(i: u8) -> CChar {
match i {
0...0x7f => CChar::Char(i as u8 as char),
0..=0x7f => CChar::Char(i as u8 as char),
_ => CChar::Raw(i as u64),
}
}
@ -84,13 +84,13 @@ impl Into<Vec<u8>> for CChar {
macro_rules! full (
($i: expr, $submac:ident!( $($args:tt)* )) => (
{
use ::nom_crate::lib::std::result::Result::*;
use crate::nom_crate::lib::std::result::Result::*;
let res = $submac!($i, $($args)*);
match res {
Ok((i, o)) => if i.len() == 0 {
Ok((i, o))
} else {
Err(::nom_crate::Err::Error(error_position!(i, ::nom_crate::ErrorKind::Custom(42))))
Err(crate::nom_crate::Err::Error(error_position!(i, crate::nom_crate::ErrorKind::Custom(42))))
},
r => r,
}
@ -106,7 +106,7 @@ macro_rules! full (
// ====================================================
macro_rules! force_type (
($input:expr,IResult<$i:ty,$o:ty,$e:ty>) => (Err::<($i,$o),Err<$i,$e>>(::nom_crate::Err::Error(error_position!($input, ErrorKind::Fix))))
($input:expr,IResult<$i:ty,$o:ty,$e:ty>) => (Err::<($i,$o),Err<$i,$e>>(crate::nom_crate::Err::Error(error_position!($input, ErrorKind::Fix))))
);
// =================================
@ -116,19 +116,19 @@ macro_rules! force_type (
macro_rules! byte (
($i:expr, $($p: pat)|* ) => ({
match $i.split_first() {
$(Some((&c @ $p,rest)))|* => Ok::<(&[_],u8),::nom_crate::Err<&[_],u32>>((rest,c)),
Some(_) => Err(::nom_crate::Err::Error(error_position!($i, ErrorKind::OneOf))),
None => Err(::nom_crate::Err::Incomplete(Needed::Size(1))),
$(Some((&c @ $p,rest)))|* => Ok::<(&[_],u8),crate::nom_crate::Err<&[_],u32>>((rest,c)),
Some(_) => Err(crate::nom_crate::Err::Error(error_position!($i, ErrorKind::OneOf))),
None => Err(crate::nom_crate::Err::Incomplete(Needed::Size(1))),
}
})
);
named!(binary<u8>, byte!(b'0'...b'1'));
named!(octal<u8>, byte!(b'0'...b'7'));
named!(decimal<u8>, byte!(b'0'...b'9'));
named!(binary<u8>, byte!(b'0'..=b'1'));
named!(octal<u8>, byte!(b'0'..=b'7'));
named!(decimal<u8>, byte!(b'0'..=b'9'));
named!(
hexadecimal<u8>,
byte!(b'0' ... b'9' | b'a' ... b'f' | b'A' ... b'F')
byte!(b'0' ..= b'9' | b'a' ..= b'f' | b'A' ..= b'F')
);
// ========================================
@ -153,7 +153,7 @@ fn c_raw_escape(n: Vec<u8>, radix: u32) -> Option<CChar> {
.ok()
.and_then(|i| u64::from_str_radix(i, radix).ok())
.map(|i| match i {
0...0x7f => CChar::Char(i as u8 as char),
0..=0x7f => CChar::Char(i as u8 as char),
_ => CChar::Raw(i),
})
}
@ -199,7 +199,7 @@ named!(
c_char<CChar>,
delimited!(
terminated!(opt!(c_width_prefix), char!('\'')),
alt!(escaped_char | map!(byte!(0 ... 91 /* \=92 */ | 93 ... 255), CChar::from)),
alt!(escaped_char | map!(byte!(0 ..= 91 /* \=92 */ | 93 ..= 255), CChar::from)),
char!('\'')
)
);
@ -234,8 +234,6 @@ fn c_int_radix(n: Vec<u8>, radix: u32) -> Option<u64> {
}
fn take_ul(input: &[u8]) -> IResult<&[u8], &[u8]> {
use nom_crate::InputTakeAtPosition;
let r = input.split_at_position(|c| c != b'u' && c != b'U' && c != b'l' && c != b'L');
match r {
Err(Err::Incomplete(_)) => Ok((&input[input.len()..], input)),
@ -324,8 +322,8 @@ named!(
// ======== main interface ========
// ================================
named!(one_literal<&[u8],EvalResult,::Error>,
fix_error!(::Error,alt_complete!(
named!(one_literal<&[u8],EvalResult,crate::Error>,
fix_error!(crate::Error,alt_complete!(
map!(full!(c_char),EvalResult::Char) |
map!(full!(c_int),|i|EvalResult::Int(::std::num::Wrapping(i))) |
map!(full!(c_float),EvalResult::Float) |
@ -337,6 +335,6 @@ named!(one_literal<&[u8],EvalResult,::Error>,
///
/// The input must contain exactly the representation of a single literal
/// token, and in particular no whitespace or sign prefixes.
pub fn parse(input: &[u8]) -> IResult<&[u8], EvalResult, ::Error> {
::assert_full_parse(one_literal(input))
pub fn parse(input: &[u8]) -> IResult<&[u8], EvalResult, crate::Error> {
crate::assert_full_parse(one_literal(input))
}

View File

@ -311,8 +311,8 @@ fn fix_bug_9069() -> bool {
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
use std::sync::{Once, ONCE_INIT};
static CHECK_FIX: Once = ONCE_INIT;
static FIX: AtomicBool = ATOMIC_BOOL_INIT;
static CHECK_FIX: Once = Once::new();
static FIX: AtomicBool = AtomicBool::new(false);
CHECK_FIX.call_once(|| FIX.store(check_bug_9069(), Ordering::SeqCst));