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//! A C expression parser and evaluator. 967c3a3e4Sopenharmony_ci//! 1067c3a3e4Sopenharmony_ci//! This crate provides methods for parsing and evaluating simple C expressions. In general, the 1167c3a3e4Sopenharmony_ci//! crate can handle most arithmetic expressions that would appear in macros or the definition of 1267c3a3e4Sopenharmony_ci//! constants, as well as string and character constants. 1367c3a3e4Sopenharmony_ci//! 1467c3a3e4Sopenharmony_ci//! The main entry point for is [`token::parse`], which parses a byte string and returns its 1567c3a3e4Sopenharmony_ci//! evaluated value. 1667c3a3e4Sopenharmony_ci#![warn(rust_2018_idioms)] 1767c3a3e4Sopenharmony_ci#![warn(missing_docs)] 1867c3a3e4Sopenharmony_ci#![allow(deprecated)] 1967c3a3e4Sopenharmony_ci 2067c3a3e4Sopenharmony_cipub mod nom { 2167c3a3e4Sopenharmony_ci //! nom's result types, re-exported. 2267c3a3e4Sopenharmony_ci pub use nom::{error::ErrorKind, error::Error, Err, IResult, Needed}; 2367c3a3e4Sopenharmony_ci} 2467c3a3e4Sopenharmony_cipub mod expr; 2567c3a3e4Sopenharmony_cipub mod literal; 2667c3a3e4Sopenharmony_cipub mod token; 2767c3a3e4Sopenharmony_ci 2867c3a3e4Sopenharmony_ci/// Parsing errors specific to C parsing 2967c3a3e4Sopenharmony_ci#[derive(Debug)] 3067c3a3e4Sopenharmony_cipub enum ErrorKind { 3167c3a3e4Sopenharmony_ci /// Expected the specified token 3267c3a3e4Sopenharmony_ci ExactToken(token::Kind, &'static [u8]), 3367c3a3e4Sopenharmony_ci /// Expected one of the specified tokens 3467c3a3e4Sopenharmony_ci ExactTokens(token::Kind, &'static [&'static str]), 3567c3a3e4Sopenharmony_ci /// Expected a token of the specified kind 3667c3a3e4Sopenharmony_ci TypedToken(token::Kind), 3767c3a3e4Sopenharmony_ci /// An unknown identifier was encountered 3867c3a3e4Sopenharmony_ci UnknownIdentifier, 3967c3a3e4Sopenharmony_ci /// An invalid literal was encountered. 4067c3a3e4Sopenharmony_ci /// 4167c3a3e4Sopenharmony_ci /// When encountered, this generally means a bug exists in the data that 4267c3a3e4Sopenharmony_ci /// was passed in or the parsing logic. 4367c3a3e4Sopenharmony_ci InvalidLiteral, 4467c3a3e4Sopenharmony_ci /// A full parse was requested, but data was left over after parsing finished. 4567c3a3e4Sopenharmony_ci Partial, 4667c3a3e4Sopenharmony_ci /// An error occurred in an underlying nom parser. 4767c3a3e4Sopenharmony_ci Parser(nom::ErrorKind), 4867c3a3e4Sopenharmony_ci} 4967c3a3e4Sopenharmony_ci 5067c3a3e4Sopenharmony_ciimpl From<nom::ErrorKind> for ErrorKind { 5167c3a3e4Sopenharmony_ci fn from(k: nom::ErrorKind) -> Self { 5267c3a3e4Sopenharmony_ci ErrorKind::Parser(k) 5367c3a3e4Sopenharmony_ci } 5467c3a3e4Sopenharmony_ci} 5567c3a3e4Sopenharmony_ci 5667c3a3e4Sopenharmony_ciimpl From<u32> for ErrorKind { 5767c3a3e4Sopenharmony_ci fn from(_: u32) -> Self { 5867c3a3e4Sopenharmony_ci ErrorKind::InvalidLiteral 5967c3a3e4Sopenharmony_ci } 6067c3a3e4Sopenharmony_ci} 6167c3a3e4Sopenharmony_ci 6267c3a3e4Sopenharmony_ci/// Parsing errors specific to C parsing. 6367c3a3e4Sopenharmony_ci/// 6467c3a3e4Sopenharmony_ci/// This is a superset of `(I, nom::ErrorKind)` that includes the additional errors specified by 6567c3a3e4Sopenharmony_ci/// [`ErrorKind`]. 6667c3a3e4Sopenharmony_ci#[derive(Debug)] 6767c3a3e4Sopenharmony_cipub struct Error<I> { 6867c3a3e4Sopenharmony_ci /// The remainder of the input stream at the time of the error. 6967c3a3e4Sopenharmony_ci pub input: I, 7067c3a3e4Sopenharmony_ci /// The error that occurred. 7167c3a3e4Sopenharmony_ci pub error: ErrorKind, 7267c3a3e4Sopenharmony_ci} 7367c3a3e4Sopenharmony_ci 7467c3a3e4Sopenharmony_ciimpl<I> From<(I, nom::ErrorKind)> for Error<I> { 7567c3a3e4Sopenharmony_ci fn from(e: (I, nom::ErrorKind)) -> Self { 7667c3a3e4Sopenharmony_ci Self::from((e.0, ErrorKind::from(e.1))) 7767c3a3e4Sopenharmony_ci } 7867c3a3e4Sopenharmony_ci} 7967c3a3e4Sopenharmony_ci 8067c3a3e4Sopenharmony_ciimpl<I> From<(I, ErrorKind)> for Error<I> { 8167c3a3e4Sopenharmony_ci fn from(e: (I, ErrorKind)) -> Self { 8267c3a3e4Sopenharmony_ci Self { 8367c3a3e4Sopenharmony_ci input: e.0, 8467c3a3e4Sopenharmony_ci error: e.1, 8567c3a3e4Sopenharmony_ci } 8667c3a3e4Sopenharmony_ci } 8767c3a3e4Sopenharmony_ci} 8867c3a3e4Sopenharmony_ci 8967c3a3e4Sopenharmony_ciimpl<I> From<::nom::error::Error<I>> for Error<I> { 9067c3a3e4Sopenharmony_ci fn from(e: ::nom::error::Error<I>) -> Self { 9167c3a3e4Sopenharmony_ci Self { 9267c3a3e4Sopenharmony_ci input: e.input, 9367c3a3e4Sopenharmony_ci error: e.code.into(), 9467c3a3e4Sopenharmony_ci } 9567c3a3e4Sopenharmony_ci } 9667c3a3e4Sopenharmony_ci} 9767c3a3e4Sopenharmony_ci 9867c3a3e4Sopenharmony_ciimpl<I> ::nom::error::ParseError<I> for Error<I> { 9967c3a3e4Sopenharmony_ci fn from_error_kind(input: I, kind: nom::ErrorKind) -> Self { 10067c3a3e4Sopenharmony_ci Self { 10167c3a3e4Sopenharmony_ci input, 10267c3a3e4Sopenharmony_ci error: kind.into(), 10367c3a3e4Sopenharmony_ci } 10467c3a3e4Sopenharmony_ci } 10567c3a3e4Sopenharmony_ci 10667c3a3e4Sopenharmony_ci fn append(_: I, _: nom::ErrorKind, other: Self) -> Self { 10767c3a3e4Sopenharmony_ci other 10867c3a3e4Sopenharmony_ci } 10967c3a3e4Sopenharmony_ci} 11067c3a3e4Sopenharmony_ci 11167c3a3e4Sopenharmony_ci// in lieu of https://github.com/Geal/nom/issues/1010 11267c3a3e4Sopenharmony_citrait ToCexprResult<I, O> { 11367c3a3e4Sopenharmony_ci fn to_cexpr_result(self) -> nom::IResult<I, O, Error<I>>; 11467c3a3e4Sopenharmony_ci} 11567c3a3e4Sopenharmony_ciimpl<I, O, E> ToCexprResult<I, O> for nom::IResult<I, O, E> 11667c3a3e4Sopenharmony_ciwhere 11767c3a3e4Sopenharmony_ci Error<I>: From<E>, 11867c3a3e4Sopenharmony_ci{ 11967c3a3e4Sopenharmony_ci fn to_cexpr_result(self) -> nom::IResult<I, O, Error<I>> { 12067c3a3e4Sopenharmony_ci match self { 12167c3a3e4Sopenharmony_ci Ok(v) => Ok(v), 12267c3a3e4Sopenharmony_ci Err(nom::Err::Incomplete(n)) => Err(nom::Err::Incomplete(n)), 12367c3a3e4Sopenharmony_ci Err(nom::Err::Error(e)) => Err(nom::Err::Error(e.into())), 12467c3a3e4Sopenharmony_ci Err(nom::Err::Failure(e)) => Err(nom::Err::Failure(e.into())), 12567c3a3e4Sopenharmony_ci } 12667c3a3e4Sopenharmony_ci } 12767c3a3e4Sopenharmony_ci} 12867c3a3e4Sopenharmony_ci 12967c3a3e4Sopenharmony_ci/// If the input result indicates a succesful parse, but there is data left, 13067c3a3e4Sopenharmony_ci/// return an `Error::Partial` instead. 13167c3a3e4Sopenharmony_cipub fn assert_full_parse<'i, I: 'i, O, E>( 13267c3a3e4Sopenharmony_ci result: nom::IResult<&'i [I], O, E>, 13367c3a3e4Sopenharmony_ci) -> nom::IResult<&'i [I], O, Error<&'i [I]>> 13467c3a3e4Sopenharmony_ciwhere 13567c3a3e4Sopenharmony_ci Error<&'i [I]>: From<E>, 13667c3a3e4Sopenharmony_ci{ 13767c3a3e4Sopenharmony_ci match result.to_cexpr_result() { 13867c3a3e4Sopenharmony_ci Ok((rem, output)) => { 13967c3a3e4Sopenharmony_ci if rem.is_empty() { 14067c3a3e4Sopenharmony_ci Ok((rem, output)) 14167c3a3e4Sopenharmony_ci } else { 14267c3a3e4Sopenharmony_ci Err(nom::Err::Error((rem, ErrorKind::Partial).into())) 14367c3a3e4Sopenharmony_ci } 14467c3a3e4Sopenharmony_ci } 14567c3a3e4Sopenharmony_ci Err(nom::Err::Incomplete(n)) => Err(nom::Err::Incomplete(n)), 14667c3a3e4Sopenharmony_ci Err(nom::Err::Failure(e)) => Err(nom::Err::Failure(e)), 14767c3a3e4Sopenharmony_ci Err(nom::Err::Error(e)) => Err(nom::Err::Error(e)), 14867c3a3e4Sopenharmony_ci } 14967c3a3e4Sopenharmony_ci} 150