From eab6db5f5f900dd04f245cc5b6e5eba53da40dbd Mon Sep 17 00:00:00 2001 From: Sven Thiele Date: Wed, 25 Oct 2023 16:30:30 +0200 Subject: [PATCH] Port to winnow --- Cargo.toml | 2 +- README.md | 11 +- examples/fz-parser.rs | 17 +- fuzz/Cargo.toml | 2 +- fuzz/fuzz_targets/fuzz_target_1.rs | 18 +- src/basic_types.rs | 28 +- src/comments.rs | 56 +-- src/constraints.rs | 267 +++++----- src/expressions.rs | 749 +++++++++++++++-------------- src/lib.rs | 5 +- src/parameters/declarations.rs | 160 +++--- src/parameters/types.rs | 165 ++----- src/predicates/declarations.rs | 136 +++--- src/predicates/types.rs | 251 ++++++---- src/primitive_literals.rs | 282 +++++------ src/solve_items.rs | 140 +++--- src/statements/mod.rs | 51 +- src/variables/declarations.rs | 494 +++++++++---------- src/variables/types.rs | 213 ++++---- 19 files changed, 1449 insertions(+), 1598 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f160fef..2869bae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ edition = "2021" exclude = ["/.github"] [dependencies] -nom = "7.0.0" +winnow = { version = "=0.5.16", features = ["alloc"] } [dev-dependencies] clap = { version = "4.2", features = ["derive"] } diff --git a/README.md b/README.md index 4a871ca..fff03c9 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ In your Cargo.toml ```toml [dependencies] -flatzinc = "0.3" +flatzinc = "0.3.20-dev" ``` In your code: @@ -22,12 +22,11 @@ In your code: ```rust use flatzinc::*; -match flatzinc::model::>(&buf) { - Ok((_, result)) => println!("{:#?}", result), - Err(Err::Error(e)) | Err(Err::Failure(e)) => { - println!("Failed to parse flatzinc!\n{}", convert_error(&buf, e)) +match flatzinc::model::>(&buf) { + Ok(result) => println!("{:#?}", result), + Err(e) => { + error!("Failed to parse flatzinc!\n{}", e) } - Err(e) => println!("Failed to parse flatzinc: {:?}", e), } ``` diff --git a/examples/fz-parser.rs b/examples/fz-parser.rs index 5ef4f1c..22914b9 100644 --- a/examples/fz-parser.rs +++ b/examples/fz-parser.rs @@ -1,12 +1,9 @@ use anyhow::Result; use clap::Parser; use log::error; -use nom::{ - error::{convert_error, VerboseError}, - Err, -}; use std::path::PathBuf; use stderrlog; +use winnow::error::ContextError; /// flatzinc parser #[derive(Parser, Debug)] @@ -32,14 +29,12 @@ fn run() -> Result<()> { let opt = Opt::parse(); let buf = std::fs::read_to_string(opt.file)?; - for line in buf.lines() { - match flatzinc::statement::>(&line) { - Ok((_, result)) => println!("{:#?}", result), - Err(Err::Error(e)) => { - let bla = convert_error(buf.as_str(), e); - error!("Failed to parse flatzinc!\n{}", bla) + for mut line in buf.lines() { + match flatzinc::statement::>(&mut line) { + Ok(result) => println!("{:#?}", result), + Err(e) => { + error!("Failed to parse flatzinc!\n{}", e) } - Err(e) => error!("Failed to parse flatzinc: {:?}", e), } } Ok(()) diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index af36b7a..5e9a84d 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -11,7 +11,7 @@ cargo-fuzz = true [dependencies] libfuzzer-sys = "0.3" -nom = "7.0.0" +winnow = "=0.5.16" [dependencies.flatzinc] path = ".." diff --git a/fuzz/fuzz_targets/fuzz_target_1.rs b/fuzz/fuzz_targets/fuzz_target_1.rs index bf8c8d5..7c4fa74 100644 --- a/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/fuzz/fuzz_targets/fuzz_target_1.rs @@ -1,21 +1,13 @@ #![no_main] -extern crate nom; +extern crate winnow; use libfuzzer_sys::fuzz_target; -pub use nom::{ - error::{convert_error, VerboseError}, - Err, -}; -use std::str; +pub use winnow::error::ContextError; fuzz_target!(|data: &[u8]| { // fuzzed code goes here - if let Ok(utf8_str) = str::from_utf8(data) { - match flatzinc::statement::>(utf8_str) { - Ok((_, result)) => println!("{:#?}", result), - Err(Err::Error(_e)) | Err(Err::Failure(_e)) => { - // let bla = convert_error(buf.as_str(), e); - // error!("Failed to parse flatzinc!\n{}", bla) - } + if let Ok(mut utf8_str) = std::str::from_utf8(data) { + match flatzinc::statement::>(&mut utf8_str) { + Ok(result) => println!("{:#?}", result), Err(e) => print!("Failed to parse flatzinc: {:?}", e), } } else { diff --git a/src/basic_types.rs b/src/basic_types.rs index 2de6c10..32e502b 100644 --- a/src/basic_types.rs +++ b/src/basic_types.rs @@ -1,6 +1,4 @@ -use std::str; - -use nom::{branch::alt, bytes::complete::tag, error::ParseError, IResult}; +use winnow::{combinator::alt, error::ParserError, token::tag, PResult, Parser}; #[derive(PartialEq, Clone, Debug)] pub enum BasicType { @@ -9,22 +7,22 @@ pub enum BasicType { Float, } -pub fn basic_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BasicType, E> { - let (input, bt) = alt((bool, float, int))(input)?; - Ok((input, bt)) +pub fn basic_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let bt = alt((bool, float, int)).parse_next(input)?; + Ok(bt) } -fn bool<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BasicType, E> { - let (input, _tag) = tag("bool")(input)?; - Ok((input, BasicType::Bool)) +fn bool<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + tag("bool").parse_next(input)?; + Ok(BasicType::Bool) } -fn int<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BasicType, E> { - let (input, _tag) = tag("int")(input)?; - Ok((input, BasicType::Int)) +fn int<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + tag("int").parse_next(input)?; + Ok(BasicType::Int) } -fn float<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BasicType, E> { - let (input, _tag) = tag("float")(input)?; - Ok((input, BasicType::Float)) +fn float<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + tag("float").parse_next(input)?; + Ok(BasicType::Float) } diff --git a/src/comments.rs b/src/comments.rs index 3f0afd0..f008e80 100644 --- a/src/comments.rs +++ b/src/comments.rs @@ -1,50 +1,42 @@ -use std::str; - -use nom::{ - branch::alt, - bytes::complete::take_till, - character::complete::{char, multispace0, multispace1}, +use winnow::{ + ascii::{multispace0, multispace1}, + combinator::alt, combinator::opt, - error::ParseError, - IResult, + error::ParserError, + token::take_till0, + PResult, Parser, }; use crate::statements::Stmt; -// white space or comments -pub fn space_or_comment0<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, &'a str, E> { - let (input, s) = alt((comment, multispace0))(input)?; - Ok((input, s)) +pub fn space_or_comment0<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<&'a str, E> { + alt((comment, multispace0)).parse_next(input) } -pub fn space_or_comment1<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, &'a str, E> { - let (input, s) = alt((comment, multispace1))(input)?; - Ok((input, s)) +pub fn space_or_comment1<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<&'a str, E> { + alt((comment, multispace1)).parse_next(input) } #[test] fn test_comment() { - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "% Comments can have anyth!ng in it really <3"; assert_eq!( - comment::>("% Comments can have anyth!ng in it really <3"), - Ok(("", " Comments can have anyth!ng in it really <3".into())) + comment::>(&mut input), + Ok(" Comments can have anyth!ng in it really <3".into()) ); } -fn comment<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> { - let (input, _) = multispace0(input)?; - let (input, _) = char('%')(input)?; - let (input, string) = take_till(|c| c == '\n')(input)?; - let (input, _) = multispace0(input)?; - let (input, _) = opt(comment)(input)?; - Ok((input, string)) +fn comment<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<&'a str, E> { + multispace0.parse_next(input)?; + '%'.parse_next(input)?; + let string = take_till0(|c| c == '\n').parse_next(input)?; + multispace0.parse_next(input)?; + opt(comment).parse_next(input)?; + Ok(string) } -pub fn space_or_comment<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Stmt, E> { - let (input, s) = space_or_comment0(input)?; - Ok((input, Stmt::Comment(s.into()))) +pub fn space_or_comment<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let s = space_or_comment0(input)?; + Ok(Stmt::Comment(s.into())) } diff --git a/src/constraints.rs b/src/constraints.rs index fd940cf..9203925 100644 --- a/src/constraints.rs +++ b/src/constraints.rs @@ -1,11 +1,8 @@ -use std::str; - -use nom::{ - bytes::complete::tag, - character::complete::char, - error::{FromExternalError, ParseError}, - multi::separated_list1, - IResult, +use winnow::{ + combinator::separated1, + error::{FromExternalError, ParserError}, + token::tag, + PResult, Parser, }; use crate::{ @@ -21,183 +18,157 @@ pub struct ConstraintItem { pub annos: Vec, } -pub fn constraint_item<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, ConstraintItem, E> +pub fn constraint_item<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("constraint")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, id) = identifier(input)?; - let (input, _) = char('(')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, exprs) = separated_list1(char(','), expr)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(')')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, annos) = annotations(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, ConstraintItem { id, exprs, annos })) + space_or_comment0(input)?; + tag("constraint").parse_next(input)?; + space_or_comment1(input)?; + let id = identifier(input)?; + '('.parse_next(input)?; + space_or_comment0(input)?; + let exprs = separated1(expr, ",").parse_next(input)?; + space_or_comment0(input)?; + ')'.parse_next(input)?; + space_or_comment0(input)?; + let annos = annotations(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(ConstraintItem { id, exprs, annos }) } #[test] fn test_constraint_item() { use crate::{AnnExpr, Annotation, Expr, IntExpr, SetLiteralExpr}; - use nom::error::VerboseError; - use std::str; + use winnow::error::ContextError; + let mut input = "constraint set_in_reif(X_26,1..2,X_52):: defines_var(X_52);"; assert_eq!( - constraint_item::>( - "constraint set_in_reif(X_26,1..2,X_52):: defines_var(X_52);" - ), - Ok(( - "", - ConstraintItem { - id: "set_in_reif".to_string(), - exprs: vec![ - Expr::VarParIdentifier("X_26".to_string()), - Expr::Set(SetLiteralExpr::IntInRange(IntExpr::Int(1), IntExpr::Int(2))), - Expr::VarParIdentifier("X_52".to_string()) - ], - annos: vec![Annotation { - id: "defines_var".to_string(), - expressions: vec![AnnExpr::Expr(Expr::VarParIdentifier("X_52".to_string()))] - }] - } - )) + constraint_item::>(&mut input), + Ok(ConstraintItem { + id: "set_in_reif".to_string(), + exprs: vec![ + Expr::VarParIdentifier("X_26".to_string()), + Expr::Set(SetLiteralExpr::IntInRange(IntExpr::Int(1), IntExpr::Int(2))), + Expr::VarParIdentifier("X_52".to_string()) + ], + annos: vec![Annotation { + id: "defines_var".to_string(), + expressions: vec![AnnExpr::Expr(Expr::VarParIdentifier("X_52".to_string()))] + }] + }) ); + let mut input = "constraint array_var_int_element(INT01, w, 2);"; assert_eq!( - constraint_item::>("constraint array_var_int_element(INT01, w, 2);"), - Ok(( - "", - ConstraintItem { - id: "array_var_int_element".to_string(), - exprs: vec![ - Expr::VarParIdentifier("INT01".to_string()), - Expr::VarParIdentifier("w".to_string()), - Expr::Int(2) - ], - annos: vec![] - } - )) + constraint_item::>(&mut input), + Ok(ConstraintItem { + id: "array_var_int_element".to_string(), + exprs: vec![ + Expr::VarParIdentifier("INT01".to_string()), + Expr::VarParIdentifier("w".to_string()), + Expr::Int(2) + ], + annos: vec![] + }) ); + let mut input = "constraint array_var_int_element(INT01, w, 2.0);"; assert_eq!( - constraint_item::>("constraint array_var_int_element(INT01, w, 2.0);"), - Ok(( - "", - ConstraintItem { - id: "array_var_int_element".to_string(), - exprs: vec![ - Expr::VarParIdentifier("INT01".to_string()), - Expr::VarParIdentifier("w".to_string()), - Expr::Float(2.0) - ], - annos: vec![] - } - )) + constraint_item::>(&mut input), + Ok(ConstraintItem { + id: "array_var_int_element".to_string(), + exprs: vec![ + Expr::VarParIdentifier("INT01".to_string()), + Expr::VarParIdentifier("w".to_string()), + Expr::Float(2.0) + ], + annos: vec![] + }) ); } - #[test] fn test_constraint_item_2() { use crate::{Expr, IntExpr}; - use nom::error::VerboseError; - use std::str; + use winnow::error::ContextError; + let mut input = "constraint int_lin_eq([-1, 1], [INT01, p], -3);"; assert_eq!( - constraint_item::>("constraint int_lin_eq([-1, 1], [INT01, p], -3);"), - Ok(( - "", - ConstraintItem { - id: "int_lin_eq".to_string(), - exprs: vec![ - Expr::ArrayOfInt(vec![IntExpr::Int(-1), IntExpr::Int(1)]), - Expr::ArrayOfInt(vec![ - IntExpr::VarParIdentifier("INT01".to_string()), - IntExpr::VarParIdentifier("p".to_string()) - ]), - Expr::Int(-3) - ], - annos: vec![] - } - )) + constraint_item::>(&mut input), + Ok(ConstraintItem { + id: "int_lin_eq".to_string(), + exprs: vec![ + Expr::ArrayOfInt(vec![IntExpr::Int(-1), IntExpr::Int(1)]), + Expr::ArrayOfInt(vec![ + IntExpr::VarParIdentifier("INT01".to_string()), + IntExpr::VarParIdentifier("p".to_string()) + ]), + Expr::Int(-3) + ], + annos: vec![] + }) ); } - #[test] fn test_constraint_item_3() { use crate::{BoolExpr, Expr}; - use nom::error::VerboseError; - use std::str; + use winnow::error::ContextError; + let mut input = "constraint float_lin_eq(X_139,[X_27,X_28,X_29],1.0);"; assert_eq!( - constraint_item::>( - "constraint float_lin_eq(X_139,[X_27,X_28,X_29],1.0);" - ), - Ok(( - "", - ConstraintItem { - id: "float_lin_eq".to_string(), - exprs: vec![ - Expr::VarParIdentifier("X_139".to_string()), - Expr::ArrayOfBool(vec![ - BoolExpr::VarParIdentifier("X_27".to_string()), - BoolExpr::VarParIdentifier("X_28".to_string()), - BoolExpr::VarParIdentifier("X_29".to_string()), - ]), - Expr::Float(1.0) - ], - annos: vec![] - } - )) + constraint_item::>(&mut input), + Ok(ConstraintItem { + id: "float_lin_eq".to_string(), + exprs: vec![ + Expr::VarParIdentifier("X_139".to_string()), + Expr::ArrayOfBool(vec![ + BoolExpr::VarParIdentifier("X_27".to_string()), + BoolExpr::VarParIdentifier("X_28".to_string()), + BoolExpr::VarParIdentifier("X_29".to_string()), + ]), + Expr::Float(1.0) + ], + annos: vec![] + }) ); } - #[test] fn test_constraint_item_4() { use crate::{BoolExpr, Expr}; - use nom::error::VerboseError; - use std::str; + use winnow::error::ContextError; + let mut input = "constraint array_bool_or([X_43,X_44],true);"; assert_eq!( - constraint_item::>("constraint array_bool_or([X_43,X_44],true);"), - Ok(( - "", - ConstraintItem { - id: "array_bool_or".to_string(), - exprs: vec![ - Expr::ArrayOfBool(vec![ - BoolExpr::VarParIdentifier("X_43".to_string()), - BoolExpr::VarParIdentifier("X_44".to_string()), - ]), - Expr::Bool(true) - ], - annos: vec![] - } - )) + constraint_item::>(&mut input), + Ok(ConstraintItem { + id: "array_bool_or".to_string(), + exprs: vec![ + Expr::ArrayOfBool(vec![ + BoolExpr::VarParIdentifier("X_43".to_string()), + BoolExpr::VarParIdentifier("X_44".to_string()), + ]), + Expr::Bool(true) + ], + annos: vec![] + }) ); } #[test] fn test_constraint_item_5() { use crate::{BoolExpr, Expr}; - use nom::error::VerboseError; - use std::str; + use winnow::error::ContextError; + let mut input = "constraint bool_clause([],[X_81,X_77]);"; assert_eq!( - constraint_item::>("constraint bool_clause([],[X_81,X_77]);"), - Ok(( - "", - ConstraintItem { - id: "bool_clause".to_string(), - exprs: vec![ - Expr::ArrayOfBool(vec![]), - Expr::ArrayOfBool(vec![ - BoolExpr::VarParIdentifier("X_81".to_string()), - BoolExpr::VarParIdentifier("X_77".to_string()) - ]) - ], - annos: vec![] - } - )) + constraint_item::>(&mut input), + Ok(ConstraintItem { + id: "bool_clause".to_string(), + exprs: vec![ + Expr::ArrayOfBool(vec![]), + Expr::ArrayOfBool(vec![ + BoolExpr::VarParIdentifier("X_81".to_string()), + BoolExpr::VarParIdentifier("X_77".to_string()) + ]) + ], + annos: vec![] + }) ); } diff --git a/src/expressions.rs b/src/expressions.rs index c4021c1..d3ca36a 100644 --- a/src/expressions.rs +++ b/src/expressions.rs @@ -1,14 +1,9 @@ -use std::str; - -use nom::{ - branch::alt, - bytes::complete::{is_not, tag, take_while_m_n}, - character::complete::{char, multispace1}, - combinator::{map, map_opt, map_res, opt, value, verify}, - error::{FromExternalError, ParseError}, - multi::{fold_many0, many0, separated_list0, separated_list1}, - sequence::{delimited, preceded}, - IResult, +use winnow::{ + ascii::multispace1, + combinator::{alt, delimited, fold_repeat, opt, preceded, repeat, separated0, separated1}, + error::{FromExternalError, ParserError}, + token::{tag, take_till1, take_while}, + PResult, Parser, }; use crate::{ @@ -20,22 +15,21 @@ use crate::{ pub type Annotations = Vec; -pub fn annotations<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Annotations, E> +pub fn annotations<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, annos) = many0(annotation1)(input)?; - Ok((input, annos)) + repeat(0.., annotation1).parse_next(input) } -fn annotation1<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Annotation, E> +fn annotation1<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = tag("::")(input)?; - let (input, _) = space_or_comment0(input)?; + tag("::").parse_next(input)?; + space_or_comment0(input)?; annotation(input) } @@ -47,32 +41,26 @@ pub struct Annotation { // ::= // | "(" "," ... ")" -fn annotation<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Annotation, E> +fn annotation<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, id) = identifier(input)?; - let (input, we) = opt(char('('))(input)?; + let id = identifier(input)?; + let we = opt('(').parse_next(input)?; if we.is_some() { - let (input, expressions_what) = separated_list1(char(','), ann_expr)(input)?; - let (input, _) = char(')')(input)?; - Ok(( - input, - Annotation { - id, - expressions: expressions_what, - }, - )) + let expressions_what = separated1(ann_expr, ',').parse_next(input)?; + ')'.parse_next(input)?; + Ok(Annotation { + id, + expressions: expressions_what, + }) } else { - let (input, _) = space_or_comment0(input)?; - Ok(( - input, - Annotation { - id, - expressions: vec![], - }, - )) + space_or_comment0(input)?; + Ok(Annotation { + id, + expressions: vec![], + }) } } @@ -86,26 +74,25 @@ pub enum AnnExpr { Expr(Expr), } -fn ann_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, AnnExpr, E> +fn ann_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, expr) = alt((ann_non_array_expr, ae_annotations))(input)?; - Ok((input, expr)) + alt((ann_non_array_expr, ae_annotations)).parse_next(input) } -fn ae_annotations<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, AnnExpr, E> +fn ae_annotations<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, res) = separated_list1(char(','), annotation)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - Ok((input, AnnExpr::Annotations(res))) + '['.parse_next(input)?; + space_or_comment0(input)?; + let res = separated1(annotation, ',').parse_next(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + Ok(AnnExpr::Annotations(res)) } // ann_non_array_expr ::= @@ -116,22 +103,21 @@ where // | var_par_id /* variable, possibly array */ // | var_par_id '[' ann_non_array_expr ']' /* array access */ // | FZ_STRING_LIT -fn ann_non_array_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, AnnExpr, E> +fn ann_non_array_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, expr) = alt((ae_expr, string_lit))(input)?; - Ok((input, expr)) + alt((ae_expr, string_lit)).parse_next(input) } -fn ae_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, AnnExpr, E> +fn ae_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, expr) = expr(input)?; - Ok((input, AnnExpr::Expr(expr))) + let expr = expr(input)?; + Ok(AnnExpr::Expr(expr)) } // @@ -145,53 +131,77 @@ where /// Parse a unicode sequence, of the form u{XXXX}, where XXXX is 1 to 6 /// hexadecimal numerals. We will combine this later with parse_escaped_char /// to parse sequences like \u{00AC}. -fn parse_unicode<'a, E>(input: &'a str) -> IResult<&'a str, char, E> -where - E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>, -{ - let parse_hex = take_while_m_n(1, 6, |c: char| c.is_ascii_hexdigit()); - - let parse_delimited_hex = preceded(char('u'), delimited(char('{'), parse_hex, char('}'))); - - let parse_u32 = map_res(parse_delimited_hex, move |hex| u32::from_str_radix(hex, 16)); - - map_opt(parse_u32, std::char::from_u32)(input) +fn parse_unicode<'a, E>(input: &mut &'a str) -> PResult +where + E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>, +{ + let parse_hex = take_while(1..6, |c: char| c.is_ascii_hexdigit()); + + let parse_delimited_hex = preceded('u', delimited('{', parse_hex, '}')); + + if let Some(hex) = opt(parse_delimited_hex).parse_next(input)? { + if let Ok(u) = u32::from_str_radix(hex, 16) { + if let Some(x) = std::char::from_u32(u) { + Ok(x) + } else { + Err(ParserError::from_error_kind( + input, + winnow::error::ErrorKind::Assert, + )) + } + } else { + Err(ParserError::from_error_kind( + input, + winnow::error::ErrorKind::Assert, + )) + } + } else { + Err(ParserError::from_error_kind( + input, + winnow::error::ErrorKind::Assert, + )) + } } /// Parse an escaped character: \n, \t, \r, \u{00AC}, etc. -fn parse_escaped_char<'a, E>(input: &'a str) -> IResult<&'a str, char, E> +fn parse_escaped_char<'a, E>(input: &mut &'a str) -> PResult, E> where - E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>, + E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>, { - preceded( - char('\\'), + let c = preceded( + '\\', alt(( parse_unicode, - value('\n', char('n')), - value('\r', char('r')), - value('\t', char('t')), - value('\u{08}', char('b')), - value('\u{0C}', char('f')), - value('\\', char('\\')), - value('/', char('/')), - value('"', char('"')), + 'n'.value('\n'), + 'r'.value('\r'), + 't'.value('\t'), + 'b'.value('\u{08}'), + 'f'.value('\u{0C}'), + '\\', + '/', + '"', )), - )(input) + ) + .parse_next(input)?; + + Ok(StringFragment::EscapedChar(c)) } /// Parse a backslash, followed by any amount of whitespace. This is used later /// to discard any escaped whitespace. -fn parse_escaped_whitespace<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, &'a str, E> { - preceded(char('\\'), multispace1)(input) +fn parse_escaped_whitespace<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> { + preceded('\\', multispace1).parse_next(input)?; + Ok(StringFragment::EscapedWS) } /// Parse a non-empty block of text that doesn't include \ or " -fn parse_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> { - let not_quote_slash = is_not("\"\\"); - - verify(not_quote_slash, |s: &str| !s.is_empty())(input) +fn parse_literal<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> { + let c = take_till1(['\"', '\\']).parse_next(input)?; + Ok(StringFragment::Literal(c)) } /// A string fragment contains a fragment of a string being parsed: either @@ -206,23 +216,24 @@ enum StringFragment<'a> { /// Combine parse_literal, parse_escaped_whitespace, and parse_escaped_char /// into a StringFragment. -fn parse_fragment<'a, E>(input: &'a str) -> IResult<&'a str, StringFragment<'a>, E> +fn parse_fragment<'a, E>(input: &mut &'a str) -> PResult, E> where - E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>, + E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>, { alt(( - map(parse_literal, StringFragment::Literal), - map(parse_escaped_char, StringFragment::EscapedChar), - value(StringFragment::EscapedWS, parse_escaped_whitespace), - ))(input) + parse_literal, + parse_escaped_char, + parse_escaped_whitespace.value(StringFragment::EscapedWS), + )) + .parse_next(input) } /// Parse a string literal, including escaped characters such as \n and \". -pub fn string_lit<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, AnnExpr, E> +pub fn string_lit<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let build_string = fold_many0(parse_fragment, String::new, |mut string, fragment| { + let build_string = fold_repeat(0.., parse_fragment, String::new, |mut string, fragment| { match fragment { StringFragment::Literal(s) => string.push_str(s), StringFragment::EscapedChar(c) => string.push(c), @@ -230,28 +241,27 @@ where } string }); - let (input, string) = delimited(char('"'), build_string, char('"'))(input)?; - Ok((input, AnnExpr::String(string))) + let string = delimited('"', build_string, '"').parse_next(input)?; + Ok(AnnExpr::String(string)) } #[test] fn test_string_lit() { - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "\"bla\""; assert_eq!( - string_lit::>("\"bla\""), - Ok(("", AnnExpr::String("bla".to_string()))) + string_lit::>(&mut input), + Ok(AnnExpr::String("bla".to_string())) ); } #[test] fn test_string_lit_escaped_characters() { - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = r#""escaped\"characters\ntest\u{0021}\u{01c3}""#; assert_eq!( - string_lit::>(r#""escaped\"characters\ntest\u{0021}\u{01c3}""#), - Ok(( - "", - AnnExpr::String("escaped\"characters\ntest!ǃ".to_string()) - )) + string_lit::>(&mut input), + Ok(AnnExpr::String("escaped\"characters\ntest!ǃ".to_string())) ); } @@ -261,21 +271,35 @@ pub enum BoolExpr { VarParIdentifier(String), } -pub fn bool_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BoolExpr, E> { - let (input, expr) = alt((be_bool_literal, be_var_par_identifier))(input)?; - Ok((input, expr)) +pub fn bool_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + alt((be_bool_literal, be_var_par_identifier)).parse_next(input) } - -fn be_bool_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BoolExpr, E> { - let (input, expr) = bool_literal(input)?; - Ok((input, BoolExpr::Bool(expr))) +#[test] +fn test_bool_expr() { + use winnow::error::ContextError; + let mut input = "true);"; + assert_eq!( + bool_expr::>(&mut input), + Ok(BoolExpr::Bool(true)) + ); } - -fn be_var_par_identifier<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BoolExpr, E> { - let (input, id) = var_par_identifier(input)?; - Ok((input, BoolExpr::VarParIdentifier(id))) +fn be_bool_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let expr = bool_literal(input)?; + Ok(BoolExpr::Bool(expr)) +} +#[test] +fn test_bool_literal() { + use winnow::error::ContextError; + let mut input = "true);"; + assert_eq!( + be_bool_literal::>(&mut input), + Ok(BoolExpr::Bool(true)) + ); + assert_eq!(input, ");"); +} +fn be_var_par_identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let id = var_par_identifier(input)?; + Ok(BoolExpr::VarParIdentifier(id)) } #[derive(PartialEq, Clone, Debug)] @@ -284,28 +308,26 @@ pub enum IntExpr { VarParIdentifier(String), } -pub fn int_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, IntExpr, E> +pub fn int_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _) = space_or_comment0(input)?; - let (input, expr) = alt((ie_int_literal, ie_var_par_identifier))(input)?; - Ok((input, expr)) + space_or_comment0(input)?; + let expr = alt((ie_int_literal, ie_var_par_identifier)).parse_next(input)?; + Ok(expr) } -fn ie_int_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, IntExpr, E> +fn ie_int_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, expr) = int_literal(input)?; - Ok((input, IntExpr::Int(expr))) + let expr = int_literal(input)?; + Ok(IntExpr::Int(expr)) } -fn ie_var_par_identifier<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, IntExpr, E> { - let (input, id) = var_par_identifier(input)?; - Ok((input, IntExpr::VarParIdentifier(id))) +fn ie_var_par_identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let id = var_par_identifier(input)?; + Ok(IntExpr::VarParIdentifier(id)) } #[derive(PartialEq, Clone, Debug)] @@ -314,27 +336,26 @@ pub enum FloatExpr { VarParIdentifier(String), } -pub fn float_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, FloatExpr, E> +pub fn float_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, expr) = alt((fe_float_literal, fe_var_par_identifier))(input)?; - Ok((input, expr)) + alt((fe_float_literal, fe_var_par_identifier)).parse_next(input) } -fn fe_float_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, FloatExpr, E> +fn fe_float_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, expr) = float_literal(input)?; - Ok((input, FloatExpr::Float(expr))) + let expr = float_literal(input)?; + Ok(FloatExpr::Float(expr)) } -fn fe_var_par_identifier<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, FloatExpr, E> { - let (input, id) = var_par_identifier(input)?; - Ok((input, FloatExpr::VarParIdentifier(id))) +fn fe_var_par_identifier<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult { + let id = var_par_identifier(input)?; + Ok(FloatExpr::VarParIdentifier(id)) } #[derive(PartialEq, Clone, Debug)] @@ -343,43 +364,48 @@ pub enum SetExpr { VarParIdentifier(String), } -pub fn set_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, SetExpr, E> +pub fn set_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, expr) = alt((se_set_literal_expr, se_var_par_identifier))(input)?; - Ok((input, expr)) + alt((se_set_literal_expr, se_var_par_identifier)).parse_next(input) } -fn se_set_literal_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, SetExpr, E> +fn se_set_literal_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, sl) = set_literal_expr(input)?; - Ok((input, SetExpr::Set(sl))) + let sl = set_literal_expr(input)?; + Ok(SetExpr::Set(sl)) } -fn se_var_par_identifier<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, SetExpr, E> { - let (input, id) = var_par_identifier(input)?; - Ok((input, SetExpr::VarParIdentifier(id))) +fn se_var_par_identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let id = var_par_identifier(input)?; + Ok(SetExpr::VarParIdentifier(id)) } #[test] fn test_expr() { - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "1..2"; assert_eq!( - expr::>("1..2"), - Ok(( - "", - Expr::Set(SetLiteralExpr::IntInRange(IntExpr::Int(1), IntExpr::Int(2))) - )) + expr::>(&mut input), + Ok(Expr::Set(SetLiteralExpr::IntInRange( + IntExpr::Int(1), + IntExpr::Int(2) + ))) ); } +#[test] +fn test_int_literal() { + use winnow::error::ContextError; + let mut input = "1"; + assert_eq!(int_literal::>(&mut input), Ok(1)); +} + #[derive(PartialEq, Clone, Debug)] pub enum Expr { VarParIdentifier(String), @@ -393,13 +419,13 @@ pub enum Expr { ArrayOfSet(Vec), } -pub fn expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> +pub fn expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = space_or_comment0(input)?; - let (input, expr) = alt(( + space_or_comment0(input)?; + let expr = alt(( e_var_par_identifier, e_bool_expr, e_set_expr, @@ -409,74 +435,75 @@ where e_array_of_int_expr, e_array_of_float_expr, e_array_of_set_expr, - ))(input)?; - Ok((input, expr)) + )) + .parse_next(input)?; + Ok(expr) } -fn e_var_par_identifier<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> { - let (input, id) = var_par_identifier(input)?; - Ok((input, Expr::VarParIdentifier(id))) +fn e_var_par_identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let id = var_par_identifier(input)?; + Ok(Expr::VarParIdentifier(id)) } -fn e_bool_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> { - let (input, b) = bool_literal(input)?; - Ok((input, Expr::Bool(b))) +fn e_bool_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let b = bool_literal(input)?; + Ok(Expr::Bool(b)) } -fn e_int_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> +fn e_int_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, int) = int_literal(input)?; - Ok((input, Expr::Int(int))) + let int = int_literal(input)?; + Ok(Expr::Int(int)) } -fn e_float_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> +fn e_float_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, float) = float_literal(input)?; - Ok((input, Expr::Float(float))) + let float = float_literal(input)?; + Ok(Expr::Float(float)) } -fn e_set_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> +fn e_set_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, set) = set_literal_expr(input)?; - Ok((input, Expr::Set(set))) + let set = set_literal_expr(input)?; + Ok(Expr::Set(set)) } -fn e_array_of_bool_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> { - let (input, v) = array_of_bool_expr_literal(input)?; - Ok((input, Expr::ArrayOfBool(v))) +fn e_array_of_bool_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let v = array_of_bool_expr_literal(input)?; + Ok(Expr::ArrayOfBool(v)) } -fn e_array_of_int_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> +fn e_array_of_int_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, v) = array_of_int_expr_literal(input)?; - Ok((input, Expr::ArrayOfInt(v))) + let v = array_of_int_expr_literal(input)?; + Ok(Expr::ArrayOfInt(v)) } -fn e_array_of_float_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> +fn e_array_of_float_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where - E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>, + E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, v) = array_of_float_expr_literal(input)?; - Ok((input, Expr::ArrayOfFloat(v))) + let v = array_of_float_expr_literal(input)?; + Ok(Expr::ArrayOfFloat(v)) } -fn e_array_of_set_expr<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Expr, E> +fn e_array_of_set_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where - E: ParseError<&'a str> + E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, v) = array_of_set_expr_literal(input)?; - Ok((input, Expr::ArrayOfSet(v))) + let v = array_of_set_expr_literal(input)?; + Ok(Expr::ArrayOfSet(v)) } #[derive(PartialEq, Clone, Debug)] @@ -487,78 +514,68 @@ pub enum SetLiteralExpr { SetInts(Vec), } -fn set_literal_expr<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, SetLiteralExpr, E> +fn set_literal_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, sl) = alt(( + alt(( sle_int_in_range, sle_bounded_float, sle_set_of_ints, sle_set_of_floats, - ))(input)?; - Ok((input, sl)) + )) + .parse_next(input) } -fn sle_int_in_range<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, SetLiteralExpr, E> +fn sle_int_in_range<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, lb) = int_expr(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("..")(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ub) = int_expr(input)?; - Ok((input, SetLiteralExpr::IntInRange(lb, ub))) + let lb = int_expr(input)?; + space_or_comment0(input)?; + tag("..").parse_next(input)?; + space_or_comment0(input)?; + let ub = int_expr(input)?; + Ok(SetLiteralExpr::IntInRange(lb, ub)) } -fn sle_bounded_float<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, SetLiteralExpr, E> +fn sle_bounded_float<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, lb) = float_expr(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("..")(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ub) = float_expr(input)?; - Ok((input, SetLiteralExpr::BoundedFloat(lb, ub))) + let lb = float_expr(input)?; + space_or_comment0(input)?; + tag("..").parse_next(input)?; + space_or_comment0(input)?; + let ub = float_expr(input)?; + Ok(SetLiteralExpr::BoundedFloat(lb, ub)) } // "{" "," ... "}" -fn sle_set_of_ints<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, SetLiteralExpr, E> +fn sle_set_of_ints<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _) = char('{')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), int_expr)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char('}')(input)?; - Ok((input, SetLiteralExpr::SetInts(v))) + '{'.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(int_expr, ',').parse_next(input)?; + space_or_comment0(input)?; + '}'.parse_next(input)?; + Ok(SetLiteralExpr::SetInts(v)) } // "{" "," ... "}" -fn sle_set_of_floats<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, SetLiteralExpr, E> +fn sle_set_of_floats<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = char('{')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), float_expr)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char('}')(input)?; - Ok((input, SetLiteralExpr::SetFloats(v))) + '{'.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(float_expr, ',').parse_next(input)?; + space_or_comment0(input)?; + '}'.parse_next(input)?; + Ok(SetLiteralExpr::SetFloats(v)) } #[derive(PartialEq, Clone, Debug)] @@ -569,69 +586,69 @@ pub enum SetLiteral { SetInts(Vec), } -pub fn set_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, SetLiteral, E> +pub fn set_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where - E: ParseError<&'a str> + E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, sl) = alt(( + alt(( sl_int_range, sl_bounded_float, sl_set_of_ints, sl_set_of_floats, - ))(input)?; - Ok((input, sl)) + )) + .parse_next(input) } -fn sl_int_range<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, SetLiteral, E> +fn sl_int_range<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, lb) = int_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("..")(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ub) = int_literal(input)?; - Ok((input, SetLiteral::IntRange(lb, ub))) + let lb = int_literal(input)?; + space_or_comment0(input)?; + tag("..").parse_next(input)?; + space_or_comment0(input)?; + let ub = int_literal(input)?; + Ok(SetLiteral::IntRange(lb, ub)) } -fn sl_bounded_float<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, SetLiteral, E> +fn sl_bounded_float<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, lb) = float_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("..")(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ub) = float_literal(input)?; - Ok((input, SetLiteral::BoundedFloat(lb, ub))) + let lb = float_literal(input)?; + space_or_comment0(input)?; + tag("..").parse_next(input)?; + space_or_comment0(input)?; + let ub = float_literal(input)?; + Ok(SetLiteral::BoundedFloat(lb, ub)) } // "{" "," ... "}" -fn sl_set_of_ints<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, SetLiteral, E> +fn sl_set_of_ints<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _) = char('{')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), int_literal)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char('}')(input)?; - Ok((input, SetLiteral::SetInts(v))) + '{'.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(int_literal, ',').parse_next(input)?; + space_or_comment0(input)?; + '}'.parse_next(input)?; + Ok(SetLiteral::SetInts(v)) } // "{" "," ... "}" -fn sl_set_of_floats<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, SetLiteral, E> +fn sl_set_of_floats<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = char('{')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), float_literal)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char('}')(input)?; - Ok((input, SetLiteral::SetFloats(v))) + '{'.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(float_literal, ',').parse_next(input)?; + space_or_comment0(input)?; + '}'.parse_next(input)?; + Ok(SetLiteral::SetFloats(v)) } #[derive(PartialEq, Clone, Debug)] @@ -640,38 +657,38 @@ pub enum ArrayOfBoolExpr { VarParIdentifier(String), } -pub fn array_of_bool_expr<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, ArrayOfBoolExpr, E> { - let (input, id) = opt(var_par_identifier)(input)?; +pub fn array_of_bool_expr<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult { + let id = opt(var_par_identifier).parse_next(input)?; if let Some(id) = id { - Ok((input, ArrayOfBoolExpr::VarParIdentifier(id))) + Ok(ArrayOfBoolExpr::VarParIdentifier(id)) } else { - let (input, v) = array_of_bool_expr_literal(input)?; - Ok((input, ArrayOfBoolExpr::Array(v))) + let v = array_of_bool_expr_literal(input)?; + Ok(ArrayOfBoolExpr::Array(v)) } } -fn array_of_bool_expr_literal<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Vec, E> { - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), bool_expr)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - Ok((input, v)) +fn array_of_bool_expr_literal<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> { + '['.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(bool_expr, ',').parse_next(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + Ok(v) } -pub fn array_of_bool_literal<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Vec, E> { - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, al) = separated_list0(char(','), bool_literal)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - Ok((input, al)) +pub fn array_of_bool_literal<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> { + '['.parse_next(input)?; + space_or_comment0(input)?; + let al = separated0(bool_literal, ',').parse_next(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + Ok(al) } #[derive(PartialEq, Clone, Debug)] @@ -680,47 +697,47 @@ pub enum ArrayOfIntExpr { VarParIdentifier(String), } -pub fn array_of_int_expr<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, ArrayOfIntExpr, E> +pub fn array_of_int_expr<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, id) = opt(var_par_identifier)(input)?; + let id = opt(var_par_identifier).parse_next(input)?; if let Some(id) = id { - Ok((input, ArrayOfIntExpr::VarParIdentifier(id))) + Ok(ArrayOfIntExpr::VarParIdentifier(id)) } else { - let (input, v) = array_of_int_expr_literal(input)?; - Ok((input, ArrayOfIntExpr::Array(v))) + let v = array_of_int_expr_literal(input)?; + Ok(ArrayOfIntExpr::Array(v)) } } -fn array_of_int_expr_literal<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Vec, E> +fn array_of_int_expr_literal<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), int_expr)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - Ok((input, v)) + '['.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(int_expr, ',').parse_next(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + Ok(v) } -pub fn array_of_int_literal<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Vec, E> +pub fn array_of_int_literal<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, al) = separated_list0(char(','), int_literal)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - Ok((input, al)) + '['.parse_next(input)?; + space_or_comment0(input)?; + let al = separated0(int_literal, ',').parse_next(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + Ok(al) } #[derive(PartialEq, Clone, Debug)] @@ -729,47 +746,47 @@ pub enum ArrayOfFloatExpr { VarParIdentifier(String), } -pub fn array_of_float_expr<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, ArrayOfFloatExpr, E> +pub fn array_of_float_expr<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, id) = opt(var_par_identifier)(input)?; + let id = opt(var_par_identifier).parse_next(input)?; if let Some(id) = id { - Ok((input, ArrayOfFloatExpr::VarParIdentifier(id))) + Ok(ArrayOfFloatExpr::VarParIdentifier(id)) } else { - let (input, v) = array_of_float_expr_literal(input)?; - Ok((input, ArrayOfFloatExpr::Array(v))) + let v = array_of_float_expr_literal(input)?; + Ok(ArrayOfFloatExpr::Array(v)) } } -fn array_of_float_expr_literal<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Vec, E> +fn array_of_float_expr_literal<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), float_expr)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - Ok((input, v)) + '['.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(float_expr, ',').parse_next(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + Ok(v) } -pub fn array_of_float_literal<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Vec, E> +pub fn array_of_float_literal<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, al) = separated_list0(char(','), float_literal)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - Ok((input, al)) + '['.parse_next(input)?; + space_or_comment0(input)?; + let al = separated0(float_literal, ',').parse_next(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + Ok(al) } #[derive(PartialEq, Clone, Debug)] @@ -778,48 +795,48 @@ pub enum ArrayOfSetExpr { VarParIdentifier(String), } -pub fn array_of_set_expr<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, ArrayOfSetExpr, E> +pub fn array_of_set_expr<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, id) = opt(var_par_identifier)(input)?; + let id = opt(var_par_identifier).parse_next(input)?; if let Some(id) = id { - Ok((input, ArrayOfSetExpr::VarParIdentifier(id))) + Ok(ArrayOfSetExpr::VarParIdentifier(id)) } else { - let (input, v) = array_of_set_expr_literal(input)?; - Ok((input, ArrayOfSetExpr::Array(v))) + let v = array_of_set_expr_literal(input)?; + Ok(ArrayOfSetExpr::Array(v)) } } -fn array_of_set_expr_literal<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Vec, E> +fn array_of_set_expr_literal<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), set_expr)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - Ok((input, v)) + '['.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(set_expr, ',').parse_next(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + Ok(v) } -pub fn array_of_set_literal<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Vec, E> +pub fn array_of_set_literal<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult, E> where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, al) = separated_list0(char(','), set_literal)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - Ok((input, al)) + '['.parse_next(input)?; + space_or_comment0(input)?; + let al = separated0(set_literal, ',').parse_next(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + Ok(al) } diff --git a/src/lib.rs b/src/lib.rs index 6c64332..0586e65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,4 @@ -pub use nom::{ - error::{convert_error, ErrorKind, FromExternalError, ParseError, VerboseError}, - Err, IResult, -}; +pub use winnow::error::{ContextError, ErrorKind, FromExternalError, ParseError}; pub use basic_types::BasicType; pub use constraints::ConstraintItem; diff --git a/src/parameters/declarations.rs b/src/parameters/declarations.rs index 1939fa8..eacfe92 100644 --- a/src/parameters/declarations.rs +++ b/src/parameters/declarations.rs @@ -1,9 +1,6 @@ -use std::str; - -use nom::{ - character::complete::char, - error::{FromExternalError, ParseError}, - IResult, +use winnow::{ + error::{FromExternalError, ParserError}, + PResult, Parser, }; use crate::{ @@ -57,84 +54,84 @@ pub enum ParDeclItem { }, } -pub fn par_decl_item<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, ParDeclItem, E> +pub fn par_decl_item<'a, E>(input: &mut &'a str) -> PResult where - E: ParseError<&'a str> + E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = space_or_comment0(input)?; - let (input, ptype) = par_type(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(':')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, id) = var_par_identifier(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char('=')(input)?; - let (input, _) = space_or_comment0(input)?; + space_or_comment0(input)?; + let ptype = par_type(input)?; + space_or_comment0(input)?; + ':'.parse_next(input)?; + space_or_comment0(input)?; + let id = var_par_identifier(input)?; + space_or_comment0(input)?; + '='.parse_next(input)?; + space_or_comment0(input)?; match ptype { ParType::BasicParType(bpt) => match bpt { BasicParType::BasicType(bt) => match bt { BasicType::Bool => { - let (input, bool) = bool_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, ParDeclItem::Bool { id, bool })) + let bool = bool_literal(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(ParDeclItem::Bool { id, bool }) } BasicType::Int => { - let (input, int) = int_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, ParDeclItem::Int { id, int })) + let int = int_literal(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(ParDeclItem::Int { id, int }) } BasicType::Float => { - let (input, float) = float_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, ParDeclItem::Float { id, float })) + let float = float_literal(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(ParDeclItem::Float { id, float }) } }, BasicParType::SetOfInt => { - let (input, set_literal) = set_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, ParDeclItem::SetOfInt { id, set_literal })) + let set_literal = set_literal(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(ParDeclItem::SetOfInt { id, set_literal }) } }, ParType::Array { ix, par_type } => match par_type { BasicParType::BasicType(bt) => match bt { BasicType::Bool => { - let (input, v) = array_of_bool_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, ParDeclItem::ArrayOfBool { ix, id, v })) + let v = array_of_bool_literal(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(ParDeclItem::ArrayOfBool { ix, id, v }) } BasicType::Int => { - let (input, v) = array_of_int_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, ParDeclItem::ArrayOfInt { ix, id, v })) + let v = array_of_int_literal(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(ParDeclItem::ArrayOfInt { ix, id, v }) } BasicType::Float => { - let (input, v) = array_of_float_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, ParDeclItem::ArrayOfFloat { ix, id, v })) + let v = array_of_float_literal(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(ParDeclItem::ArrayOfFloat { ix, id, v }) } }, BasicParType::SetOfInt => { - let (input, v) = array_of_set_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, ParDeclItem::ArrayOfSet { ix, id, v })) + let v = array_of_set_literal(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(ParDeclItem::ArrayOfSet { ix, id, v }) } }, } @@ -143,46 +140,43 @@ where #[test] fn test_par_decl_item_1() { use crate::IndexSet; - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "array [1..3] of float: X_139 = [1.0,1.0,1.0];"; assert_eq!( - par_decl_item::>("array [1..3] of float: X_139 = [1.0,1.0,1.0];"), - Ok(( - "", - ParDeclItem::ArrayOfFloat { - ix: IndexSet(3), - id: "X_139".to_string(), - v: vec![1.0, 1.0, 1.0] - } - )) + par_decl_item::>(&mut input), + Ok(ParDeclItem::ArrayOfFloat { + ix: IndexSet(3), + id: "X_139".to_string(), + v: vec![1.0, 1.0, 1.0] + }) ); } #[test] #[should_panic] fn test_par_decl_item_2() { - use nom::error::VerboseError; use std::str; - par_decl_item::>("bool : b2 = b1;").unwrap(); + use winnow::error::ContextError; + let mut input = "bool : b2 = b1;"; + par_decl_item::>(&mut input).unwrap(); } #[test] fn test_par_decl_item_3() { use crate::IndexSet; use crate::SetLiteral; - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "array [1..3] of set of int : h = [{42,17},1..5,{}];"; assert_eq!( - par_decl_item::>("array [1..3] of set of int : h = [{42,17},1..5,{}];"), - Ok(( - "", - ParDeclItem::ArrayOfSet { - ix: IndexSet(3), - id: "h".to_string(), - v: vec![ - SetLiteral::SetInts(vec![42, 17]), - SetLiteral::IntRange(1, 5), - SetLiteral::SetInts(vec![]) - ] - } - )) + par_decl_item::>(&mut input), + Ok(ParDeclItem::ArrayOfSet { + ix: IndexSet(3), + id: "h".to_string(), + v: vec![ + SetLiteral::SetInts(vec![42, 17]), + SetLiteral::IntRange(1, 5), + SetLiteral::SetInts(vec![]) + ] + }) ); } diff --git a/src/parameters/types.rs b/src/parameters/types.rs index e11d424..51268a2 100644 --- a/src/parameters/types.rs +++ b/src/parameters/types.rs @@ -1,11 +1,8 @@ -use std::str; - -use nom::{ - branch::alt, - bytes::complete::tag, - character::complete::char, - error::{FromExternalError, ParseError}, - IResult, +use winnow::{ + combinator::alt, + error::{FromExternalError, ParserError}, + token::tag, + PResult, Parser, }; use crate::{ @@ -20,27 +17,26 @@ pub enum BasicParType { SetOfInt, } -pub fn basic_par_type<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicParType, E> { - let (input, bpt) = alt((bpt_basic_type, bpt_set_of_int))(input)?; - Ok((input, bpt)) +pub fn basic_par_type<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult { + alt((bpt_basic_type, bpt_set_of_int)).parse_next(input) } -fn bpt_basic_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BasicParType, E> { - let (input, bt) = basic_type(input)?; - Ok((input, BasicParType::BasicType(bt))) +fn bpt_basic_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let bt = basic_type(input)?; + Ok(BasicParType::BasicType(bt)) } // "set" "of" "int" // Moved this be a basic-var-type basic-par-type -fn bpt_set_of_int<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BasicParType, E> { - let (input, _tag) = tag("set")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _tag) = tag("of")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _tag) = tag("int")(input)?; - Ok((input, BasicParType::SetOfInt)) +fn bpt_set_of_int<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + tag("set").parse_next(input)?; + space_or_comment1(input)?; + tag("of").parse_next(input)?; + space_or_comment1(input)?; + tag("int").parse_next(input)?; + Ok(BasicParType::SetOfInt) } #[derive(PartialEq, Clone, Debug)] @@ -55,116 +51,43 @@ pub enum ParType { #[test] fn test_par_type() { use crate::IndexSet; - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "array [1..3] of float"; assert_eq!( - par_type::>("array [1..3] of float"), - Ok(( - "", - ParType::Array { - ix: IndexSet(3), - par_type: BasicParType::BasicType(BasicType::Float) - } - )) + par_type::>(&mut input), + Ok(ParType::Array { + ix: IndexSet(3), + par_type: BasicParType::BasicType(BasicType::Float) + }) ); } -pub fn par_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, ParType, E> +pub fn par_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, par_type) = alt((pt_basic_par_type, array_par_type))(input)?; - Ok((input, par_type)) + alt((pt_basic_par_type, array_par_type)).parse_next(input) } -fn pt_basic_par_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, ParType, E> { - let (input, pt) = basic_par_type(input)?; - Ok((input, ParType::BasicParType(pt))) +fn pt_basic_par_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let pt = basic_par_type(input)?; + Ok(ParType::BasicParType(pt)) } -fn array_par_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, ParType, E> +fn array_par_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _) = tag("array")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ix) = index_set(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _tag) = tag("of")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, par_type) = basic_par_type(input)?; - Ok((input, ParType::Array { ix, par_type })) -} - -#[test] -fn test_basic_pred_par_type() { - use crate::predicates::types; - use crate::predicates::types::BasicPredParType; - use nom::error::VerboseError; - assert_eq!( - types::basic_pred_par_type::>("var set of int"), - Ok(("", BasicPredParType::VarSetOfInt)) - ); -} - -#[test] -fn test_pred_par_type_range() { - use crate::predicates::types; - use nom::error::VerboseError; - assert_eq!( - types::pred_par_type::>("1..3"), - Ok(( - "", - types::PredParType::Basic(types::BasicPredParType::IntInRange(1, 3)) - )) - ); -} - -#[test] -fn test_pred_par_type_2() { - use crate::predicates::types; - use nom::error::VerboseError; - assert_eq!( - types::pred_par_type::>("array [1..1] of var set of int"), - Ok(( - "", - types::PredParType::Array { - ix: types::PredIndexSet::IndexSet(1), - par_type: types::BasicPredParType::VarSetOfInt, - }, - )) - ); -} - -#[test] -fn test_pred_par_type_3() { - use crate::predicates::types; - use nom::error::VerboseError; - assert_eq!( - types::pred_par_type::>("var set of int"), - Ok(( - "", - types::PredParType::Basic(types::BasicPredParType::VarSetOfInt) - )) - ); -} - -#[test] -fn test_pred_par_type_ident_pair() { - use crate::predicates::declarations; - use crate::predicates::types; - use nom::error::VerboseError; - assert_eq!( - declarations::pred_par_type_ident_pair::>("var set of int: g"), - Ok(( - "", - ( - types::PredParType::Basic(types::BasicPredParType::VarSetOfInt), - "g".to_string() - ) - )) - ); + tag("array").parse_next(input)?; + space_or_comment1(input)?; + '['.parse_next(input)?; + space_or_comment0(input)?; + let ix = index_set(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + space_or_comment1(input)?; + tag("of").parse_next(input)?; + space_or_comment1(input)?; + let par_type = basic_par_type(input)?; + Ok(ParType::Array { ix, par_type }) } diff --git a/src/predicates/declarations.rs b/src/predicates/declarations.rs index 9697e29..483f0fa 100644 --- a/src/predicates/declarations.rs +++ b/src/predicates/declarations.rs @@ -1,11 +1,8 @@ -use std::str; - -use nom::{ - bytes::complete::tag, - character::complete::char, - error::{FromExternalError, ParseError}, - multi::separated_list1, - IResult, +use winnow::{ + combinator::separated1, + error::{FromExternalError, ParserError}, + token::tag, + PResult, Parser, }; use crate::{ @@ -20,86 +17,93 @@ pub struct PredicateItem { pub parameters: Vec<(PredParType, String)>, } -pub fn predicate_item<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, PredicateItem, E> -where - E: FromExternalError<&'a str, std::num::ParseIntError> - + FromExternalError<&'a str, std::num::ParseFloatError>, -{ - let (input, _) = space_or_comment0(input)?; - let (input, _) = tag("predicate")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, id) = identifier(input)?; - let (input, _) = char('(')(input)?; - let (input, parameters) = separated_list1(char(','), pred_par_type_ident_pair)(input)?; - let (input, _) = char(')')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, PredicateItem { id, parameters })) -} - -pub fn pred_par_type_ident_pair<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, (PredParType, String), E> +pub fn predicate_item<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = space_or_comment0(input)?; - let (input, pred_par_type) = pred_par_type(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(':')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ident) = identifier(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, (pred_par_type, ident))) + space_or_comment0(input)?; + tag("predicate").parse_next(input)?; + space_or_comment1(input)?; + let id = identifier(input)?; + '('.parse_next(input)?; + let parameters = separated1(pred_par_type_ident_pair, ",").parse_next(input)?; + ')'.parse_next(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(PredicateItem { id, parameters }) } #[test] fn test_predicate_item() { use crate::predicates::types::BasicPredParType; - use nom::error::VerboseError; use std::str; + use winnow::error::ContextError; + let mut input = "predicate float_03({1.0,3.3}:c);"; assert_eq!( - predicate_item::>("predicate float_03({1.0,3.3}:c);"), - Ok(( - "", - PredicateItem { - id: "float_03".to_string(), - parameters: vec![( - PredParType::Basic(BasicPredParType::FloatInSet(vec![1.0, 3.3])), - "c".to_string() - )] - } - )) + predicate_item::>(&mut input), + Ok(PredicateItem { + id: "float_03".to_string(), + parameters: vec![( + PredParType::Basic(BasicPredParType::FloatInSet(vec![1.0, 3.3])), + "c".to_string() + )] + }) ); } #[test] fn test_predicate_item2() { use crate::predicates::types::BasicPredParType; - use nom::error::VerboseError; use std::str; + use winnow::error::ContextError; + let mut input = "predicate my_pred({1.0,3.3}:c);"; assert_eq!( - predicate_item::>("predicate my_pred({1.0,3.3}:c);"), - Ok(( - "", - PredicateItem { - id: "my_pred".to_string(), - parameters: vec![( - PredParType::Basic(BasicPredParType::FloatInSet(vec![1.0, 3.3])), - "c".to_string() - )] - } - )) + predicate_item::>(&mut input), + Ok(PredicateItem { + id: "my_pred".to_string(), + parameters: vec![( + PredParType::Basic(BasicPredParType::FloatInSet(vec![1.0, 3.3])), + "c".to_string() + )] + }) ); } - #[test] #[should_panic] fn test_predicate_item_3() { - use nom::error::VerboseError; use std::str; - predicate_item::>("predicate float_01(set of float:c);").unwrap(); + use winnow::error::ContextError; + let mut input = "predicate float_01(set of float:c);"; + predicate_item::>(&mut input).unwrap(); +} +pub fn pred_par_type_ident_pair<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult<(PredParType, String), E> +where + E: FromExternalError<&'a str, std::num::ParseIntError> + + FromExternalError<&'a str, std::num::ParseFloatError>, +{ + space_or_comment0(input)?; + let pred_par_type = pred_par_type(input)?; + space_or_comment0(input)?; + ':'.parse_next(input)?; + space_or_comment0(input)?; + let ident = identifier(input)?; + space_or_comment0(input)?; + Ok((pred_par_type, ident)) +} +#[test] +fn test_pred_par_type_ident_pair() { + use crate::predicates::declarations; + use crate::predicates::types; + use winnow::error::ContextError; + let mut input = "var set of int: g"; + assert_eq!( + declarations::pred_par_type_ident_pair::>(&mut input), + Ok(( + types::PredParType::Basic(types::BasicPredParType::VarSetOfInt), + "g".to_string() + )) + ); } diff --git a/src/predicates/types.rs b/src/predicates/types.rs index 49a61dd..9512183 100644 --- a/src/predicates/types.rs +++ b/src/predicates/types.rs @@ -1,11 +1,8 @@ -use std::str; - -use nom::{ - branch::alt, - bytes::complete::tag, - character::complete::char, - error::{FromExternalError, ParseError}, - IResult, +use winnow::{ + combinator::alt, + error::{FromExternalError, ParserError}, + token::tag, + PResult, Parser, }; use crate::{ @@ -31,14 +28,14 @@ pub enum BasicPredParType { SubSetOfIntRange(i128, i128), } -pub fn basic_pred_par_type<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> +pub fn basic_pred_par_type<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, bppt) = alt(( + alt(( bppt_basic_par_type, bppt_basic_var_type, bppt_var_set_of_int, @@ -48,101 +45,109 @@ where bppt_float_in_set, bppt_subset_of_int_set, bppt_subset_of_int_range, - ))(input)?; - Ok((input, bppt)) + )) + .parse_next(input) } - -fn bppt_basic_par_type<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> { - let (input, bpt) = basic_par_type(input)?; - Ok((input, BasicPredParType::BasicParType(bpt))) +#[test] +fn test_basic_pred_par_type() { + use crate::predicates::types; + use crate::predicates::types::BasicPredParType; + use winnow::error::ContextError; + let mut input = "var set of int"; + assert_eq!( + types::basic_pred_par_type::>(&mut input), + Ok(BasicPredParType::VarSetOfInt) + ); +} +fn bppt_basic_par_type<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult { + let bpt = basic_par_type(input)?; + Ok(BasicPredParType::BasicParType(bpt)) } -fn bppt_basic_var_type<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> +fn bppt_basic_var_type<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, bvt) = basic_var_type(input)?; - Ok((input, BasicPredParType::BasicVarType(bvt))) -} - -fn bppt_var_set_of_int<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> { - let (input, _) = space_or_comment0(input)?; - let (input, _) = tag("var")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _) = tag("set")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _) = tag("of")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _) = tag("int")(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, BasicPredParType::VarSetOfInt)) -} - -fn bppt_int_in_range<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> + let bvt = basic_var_type(input)?; + Ok(BasicPredParType::BasicVarType(bvt)) +} + +fn bppt_var_set_of_int<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult { + space_or_comment0(input)?; + tag("var").parse_next(input)?; + space_or_comment1(input)?; + tag("set").parse_next(input)?; + space_or_comment1(input)?; + tag("of").parse_next(input)?; + space_or_comment1(input)?; + tag("int").parse_next(input)?; + space_or_comment0(input)?; + Ok(BasicPredParType::VarSetOfInt) +} + +fn bppt_int_in_range<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, (lb, ub)) = int_in_range(input)?; - Ok((input, BasicPredParType::IntInRange(lb, ub))) + let (lb, ub) = int_in_range(input)?; + Ok(BasicPredParType::IntInRange(lb, ub)) } -fn bppt_int_in_set<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> +fn bppt_int_in_set<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, set) = int_in_set(input)?; - Ok((input, BasicPredParType::IntInSet(set))) + let set = int_in_set(input)?; + Ok(BasicPredParType::IntInSet(set)) } -fn bppt_bounded_float<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> +fn bppt_bounded_float<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, (lb, ub)) = bounded_float(input)?; - Ok((input, BasicPredParType::BoundedFloat(lb, ub))) + let (lb, ub) = bounded_float(input)?; + Ok(BasicPredParType::BoundedFloat(lb, ub)) } -fn bppt_float_in_set<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> +fn bppt_float_in_set<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, set) = float_in_set(input)?; - Ok((input, BasicPredParType::FloatInSet(set))) + let set = float_in_set(input)?; + Ok(BasicPredParType::FloatInSet(set)) } -fn bppt_subset_of_int_range<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> +fn bppt_subset_of_int_range<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, (lb, ub)) = subset_of_int_range(input)?; - Ok((input, BasicPredParType::SubSetOfIntRange(lb, ub))) + let (lb, ub) = subset_of_int_range(input)?; + Ok(BasicPredParType::SubSetOfIntRange(lb, ub)) } -fn bppt_subset_of_int_set<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicPredParType, E> +fn bppt_subset_of_int_set<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, set) = subset_of_int_set(input)?; - Ok((input, BasicPredParType::SubSetOfIntSet(set))) + let set = subset_of_int_set(input)?; + Ok(BasicPredParType::SubSetOfIntSet(set)) } #[derive(PartialEq, Clone, Debug)] @@ -154,46 +159,81 @@ pub enum PredParType { }, } -pub fn pred_par_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, PredParType, E> +pub fn pred_par_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, ppt) = alt((ppt_basic_pred_par_type, array_of_pred_index_set))(input)?; - Ok((input, ppt)) + alt((ppt_basic_pred_par_type, array_of_pred_index_set)).parse_next(input) } - -fn ppt_basic_pred_par_type<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, PredParType, E> +#[test] +fn test_pred_par_type_range() { + use crate::predicates::types; + use winnow::error::ContextError; + let mut input = "1..3"; + assert_eq!( + types::pred_par_type::>(&mut input), + Ok(types::PredParType::Basic( + types::BasicPredParType::IntInRange(1, 3) + )) + ); +} +#[test] +fn test_pred_par_type_2() { + use crate::predicates::types; + use winnow::error::ContextError; + let mut input = "array [1..1] of var set of int"; + assert_eq!( + pred_par_type::>(&mut input), + Ok(PredParType::Array { + ix: types::PredIndexSet::IndexSet(1), + par_type: types::BasicPredParType::VarSetOfInt, + },) + ); +} +#[test] +fn test_pred_par_type_3() { + use crate::predicates::types; + use winnow::error::ContextError; + let mut input = "var set of int"; + assert_eq!( + types::pred_par_type::>(&mut input), + Ok(types::PredParType::Basic( + types::BasicPredParType::VarSetOfInt + )) + ); +} +fn ppt_basic_pred_par_type<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, bppt) = basic_pred_par_type(input)?; - Ok((input, PredParType::Basic(bppt))) + let bppt = basic_pred_par_type(input)?; + Ok(PredParType::Basic(bppt)) } -fn array_of_pred_index_set<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, PredParType, E> +fn array_of_pred_index_set<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("array")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ix) = pred_index_set(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _tag) = tag("of")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, par_type) = basic_pred_par_type(input)?; - Ok((input, PredParType::Array { ix, par_type })) + space_or_comment0(input)?; + tag("array").parse_next(input)?; + space_or_comment1(input)?; + '['.parse_next(input)?; + space_or_comment0(input)?; + let ix = pred_index_set(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + space_or_comment1(input)?; + tag("of").parse_next(input)?; + space_or_comment1(input)?; + let par_type = basic_pred_par_type(input)?; + Ok(PredParType::Array { ix, par_type }) } #[derive(PartialEq, Clone, Debug)] @@ -202,23 +242,22 @@ pub enum PredIndexSet { Int, } -fn pred_index_set<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, PredIndexSet, E> +fn pred_index_set<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, index_set) = alt((pis_int, pis_index_set))(input)?; - Ok((input, index_set)) + alt((pis_int, pis_index_set)).parse_next(input) } -fn pis_int<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, PredIndexSet, E> { - let (input, _tag) = tag("int")(input)?; - Ok((input, PredIndexSet::Int)) +fn pis_int<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + tag("int").parse_next(input)?; + Ok(PredIndexSet::Int) } -fn pis_index_set<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, PredIndexSet, E> +fn pis_index_set<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, ix) = index_set(input)?; - Ok((input, PredIndexSet::IndexSet(ix.0))) + let ix = index_set(input)?; + Ok(PredIndexSet::IndexSet(ix.0)) } diff --git a/src/primitive_literals.rs b/src/primitive_literals.rs index 6e450a3..18f3562 100644 --- a/src/primitive_literals.rs +++ b/src/primitive_literals.rs @@ -1,43 +1,46 @@ -use std::str; - -use nom::{ - branch::alt, - bytes::complete::{tag, take_while, take_while1}, - character::complete::{char, one_of}, - combinator::{map_res, opt, value}, - error::{ErrorKind, FromExternalError, ParseError}, - IResult, +use winnow::{ + combinator::{alt, opt}, + error::{ErrorKind, FromExternalError, ParserError}, + token::{one_of, tag, take_while}, + PResult, Parser, }; -pub fn identifier<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, String, E> { - let (input, first) = one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")(input)?; - let (input, rest) = take_while(is_identifier_rest)(input)?; +pub fn identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let first = one_of([ + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + ]) + .parse_next(input)?; + let rest = take_while(0.., is_identifier_rest).parse_next(input)?; let combine = format!("{}{}", first, rest); // check for reserved key words if is_reserved_key_word(&combine) { - Err(crate::Err::Error(ParseError::from_error_kind( - input, - ErrorKind::IsA, - ))) + Err(winnow::error::ErrMode::Backtrack( + ParserError::from_error_kind(input, ErrorKind::Token), + )) } else { - Ok((input, combine)) + Ok(combine) } } -pub fn var_par_identifier<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, String, E> { - let (input, first) = one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_")(input)?; - let (input, rest) = take_while(is_identifier_rest)(input)?; +pub fn var_par_identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let first = one_of([ + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', + ]) + .parse_next(input)?; + + let rest = take_while(0.., is_identifier_rest).parse_next(input)?; let combine = format!("{}{}", first, rest); // check for reserved key words if is_reserved_key_word(&combine) { - Err(crate::Err::Error(ParseError::from_error_kind( - input, - ErrorKind::IsA, - ))) + Err(winnow::error::ErrMode::Backtrack( + ParserError::from_error_kind(input, ErrorKind::Token), + )) } else { - Ok((input, combine)) + Ok(combine) } } @@ -95,7 +98,6 @@ fn is_reserved_key_word(string: &str) -> bool { } fn is_identifier_rest(c: char) -> bool { - //one_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789")(input.into()) { matches!( c, 'a' | 'b' @@ -163,197 +165,203 @@ fn is_identifier_rest(c: char) -> bool { ) } -pub fn bool_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, bool, E> { - alt((value(true, tag("true")), value(false, tag("false"))))(input) +pub fn bool_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + alt((tag("true").value(true), tag("false").value(false))).parse_next(input) } -pub fn int_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, i128, E> +pub fn int_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _) = crate::comments::space_or_comment0(input)?; - let (input, int) = alt((decimal, hexadecimal, octal))(input)?; - Ok((input, int as i128)) + crate::comments::space_or_comment0(input)?; + alt((decimal, hexadecimal, octal)).parse_next(input) } -fn decimal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, i128, E> +fn decimal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, negation) = opt(char('-'))(input)?; - let (input, int) = map_res(take_while1(is_dec_digit), from_dec)(input)?; + let negation = opt('-').parse_next(input)?; + let int = take_while(1.., is_dec_digit).parse_next(input)?; + let int = int + .parse::() + .map_err(|e| winnow::error::ErrMode::from_external_error(input, ErrorKind::Verify, e))?; if negation.is_some() { - Ok((input, -(int as i128))) + Ok(-(int as i128)) } else { - Ok((input, int as i128)) + Ok(int as i128) } } - +#[test] +fn test_decimal() { + use winnow::error::ContextError; + let mut input = "170141183460469231731687303715884105727"; + assert_eq!( + decimal::>(&mut input), + Ok(170141183460469231731687303715884105727) + ); +} +//Should fail because of overflow +// #[test] +// fn test_decimal2() { +// use winnow::error::ContextError; +// let mut input = "170141183460469231731687303715884105728"; +// assert_eq!(decimal::>(&mut input), Ok(170141183460469231731687303715884105727)); +// } #[test] fn test_hex() { - use nom::error::VerboseError; - assert_eq!(hexadecimal::>("-0x2f"), Ok(("", -47))); + use winnow::error::ContextError; + let mut input = "-0x2f"; + assert_eq!(hexadecimal::>(&mut input), Ok(-47)); } -fn hexadecimal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, i128, E> +fn hexadecimal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, negation) = opt(char('-'))(input)?; - let (input, _tag) = tag("0x")(input)?; - let (input, int) = map_res(take_while1(is_hex_digit), from_hex)(input)?; + let negation = opt('-').parse_next(input)?; + tag("0x").parse_next(input)?; + let int = take_while(1.., is_hex_digit).parse_next(input)?; + let int = u128::from_str_radix(int, 16) + .map_err(|e| winnow::error::ErrMode::from_external_error(input, ErrorKind::Verify, e))?; + if negation.is_some() { - Ok((input, -(int as i128))) + Ok(-(int as i128)) } else { - Ok((input, int as i128)) + Ok(int as i128) } } -#[test] -fn test_oct() { - use nom::error::VerboseError; - assert_eq!(octal::>("0o21"), Ok(("", 17))); -} - -fn octal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, i128, E> +fn octal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, negation) = opt(char('-'))(input)?; - let (input, _tag) = tag("0o")(input)?; - let (input, int) = map_res(take_while1(is_oct_digit), from_oct)(input)?; + let negation = opt('-').parse_next(input)?; + tag("0o").parse_next(input)?; + let int = take_while(1.., is_oct_digit).parse_next(input)?; + let int = u128::from_str_radix(int, 8) + .map_err(|e| winnow::error::ErrMode::from_external_error(input, ErrorKind::Verify, e))?; if negation.is_some() { - Ok((input, -(int as i128))) + Ok(-(int as i128)) } else { - Ok((input, int as i128)) + Ok(int as i128) } } -fn from_hex(input: &str) -> Result { - u8::from_str_radix(input, 16) +#[test] +fn test_oct() { + use winnow::error::ContextError; + let mut input = "0o200000000000000000000000000000000001"; + assert_eq!( + octal::>(&mut input), + Ok(81129638414606681695789005144065) + ); } fn is_hex_digit(c: char) -> bool { - c.is_digit(16) -} - -fn from_oct(input: &str) -> Result { - u8::from_str_radix(input, 8) + c.is_ascii_hexdigit() } fn is_oct_digit(c: char) -> bool { c.is_digit(8) } -fn from_dec(input: &str) -> Result { - input.parse::() -} - -fn from_float(input: &str) -> Result { - input.parse::() -} - fn is_dec_digit(c: char) -> bool { - c.is_digit(10) + c.is_ascii_digit() } #[test] fn test_float() { - use nom::error::VerboseError; + use winnow::error::ContextError; //TODO should return error - // float_literal::>("5") + // float_literal::>("5") + let mut input = "023.21"; + assert_eq!(float_literal::>(&mut input), Ok(023.21)); + let mut input = "0023.21E-098"; assert_eq!( - float_literal::>("023.21"), - Ok(("", 023.21)) + float_literal::>(&mut input), + Ok(0023.21E-098) ); + let mut input = "0023.21e+098"; assert_eq!( - float_literal::>("0023.21E-098"), - Ok(("", 0023.21E-098)) + float_literal::>(&mut input), + Ok(0023.21e+098) ); + let mut input = "002e+098"; assert_eq!( - float_literal::>("0023.21e+098"), - Ok(("", 0023.21e+098)) + float_literal::>(&mut input), + Ok(002e+098) ); + let mut input = "0.21"; + assert_eq!(float_literal::>(&mut input), Ok(0.21)); + let mut input = "1.0,"; + assert_eq!(float_literal::>(&mut input), Ok(1.0)); + + let mut input = "0.000000000000000000000000000000007609999999000000000000000000000000760999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999900000000000000000000000764DD4DDDDDDDDD% + "; assert_eq!( - float_literal::>("002e+098"), - Ok(("", 002e+098)) + float_literal::>(&mut input), + Ok(0.000000000000000000000000000000007609999999) ); - assert_eq!(float_literal::>("0.21"), Ok(("", 0.21))); - assert_eq!(float_literal::>("1.0,"), Ok((",", 1.0))); - - assert_eq!(float_literal::>("0.000000000000000000000000000000007609999999000000000000000000000000760999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999900000000000000000000000764DD4DDDDDDDDD% - "), Ok(("DD4DDDDDDDDD%\n ", 0.000000000000000000000000000000007609999999))); } -pub fn float_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, f64, E> +pub fn float_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = crate::comments::space_or_comment0(input)?; - let (input, f) = fz_float(input)?; - Ok((input, f)) + crate::comments::space_or_comment0(input)?; + fz_float(input) } -fn fz_float<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, f64, E> +fn fz_float<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input2, fl) = map_res(alt((fz_float1, fz_float2)), from_float)(input)?; - Ok((input2, fl)) + let mut fl = alt((fz_float1, fz_float2)).parse_next(input)?; + winnow::ascii::float.parse_next(&mut fl) } -fn fz_float1<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> { - let (input1, sign) = opt(char('-'))(input)?; - let (input2, a) = take_while1(is_dec_digit)(input1)?; - let (input3, _) = char('.')(input2)?; - let (input4, b) = take_while1(is_dec_digit)(input3)?; - let (input5, rest) = opt(bpart)(input4)?; - let len = if sign.is_some() { - if let Some(rest) = rest { - 1 + a.len() + 1 + b.len() + rest.len() - } else { - 1 + a.len() + 1 + b.len() - } - } else if let Some(rest) = rest { - a.len() + 1 + b.len() + rest.len() - } else { - a.len() + 1 + b.len() - }; - Ok((input5, &input[..len])) +fn fz_float1<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<&'a str, E> { + let sign = opt('-'); + + let pre = take_while(1.., is_dec_digit); + let post = take_while(1.., is_dec_digit); + let rest = opt(bpart); + + (sign, pre, '.', post, rest).recognize().parse_next(input) } -fn fz_float2<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> { - let (input1, sign) = opt(char('-'))(input)?; - let (input2, digits) = take_while1(is_dec_digit)(input1)?; - let (input3, rest) = bpart(input2)?; - let len = if sign.is_some() { - 1 + digits.len() + rest.len() - } else { - digits.len() + rest.len() - }; - Ok((input3, &input[..len])) +fn fz_float2<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<&'a str, E> { + let sign = opt('-'); + let digits = take_while(1.., is_dec_digit); + let e = alt(('e', 'E')); + let sign2 = opt(alt((tag("-"), tag("+")))); + let digits2 = take_while(1.., is_dec_digit); + (sign, digits, e, sign2, digits2) + .recognize() + .parse_next(input) } -fn bpart<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, String, E> { - let (input, e) = alt((tag("e"), tag("E")))(input)?; - let (input, sign) = opt(alt((tag("-"), tag("+"))))(input)?; - let (input, digits) = take_while1(is_dec_digit)(input)?; +fn bpart<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let e = alt(('e', 'E')).parse_next(input)?; + let sign = opt(alt((tag("-"), tag("+")))).parse_next(input)?; + let digits = take_while(1.., is_dec_digit).parse_next(input)?; if let Some(sign) = sign { - Ok((input, format!("{}{}{}", e, sign, digits))) + Ok(format!("{}{}{}", e, sign, digits)) } else { - Ok((input, format!("{}{}", e, digits))) + Ok(format!("{}{}", e, digits)) } } #[derive(PartialEq, Clone, Debug)] pub struct IndexSet(pub i128); -pub fn index_set<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, IndexSet, E> +pub fn index_set<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _) = char('1')(input)?; - let (input, _tag) = tag("..")(input)?; - let (input, int) = int_literal(input)?; - Ok((input, IndexSet(int))) + '1'.parse_next(input)?; + tag("..").parse_next(input)?; + let int = int_literal.parse_next(input)?; + Ok(IndexSet(int)) } diff --git a/src/solve_items.rs b/src/solve_items.rs index cbeb187..3f5c21a 100644 --- a/src/solve_items.rs +++ b/src/solve_items.rs @@ -1,11 +1,8 @@ -use std::str; - -use nom::{ - branch::alt, - bytes::complete::tag, - character::complete::char, - error::{FromExternalError, ParseError}, - IResult, +use winnow::{ + combinator::alt, + error::{FromExternalError, ParserError}, + token::tag, + PResult, Parser, }; use crate::{ @@ -22,27 +19,28 @@ pub struct SolveItem { pub annotations: Annotations, } -pub fn solve_item<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, SolveItem, E> +pub fn solve_item<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = space_or_comment0(input)?; - let (input, _) = tag("solve")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, annotations) = annotations(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, goal) = alt(( + space_or_comment0(input)?; + tag("solve").parse_next(input)?; + space_or_comment1(input)?; + let annotations = annotations(input)?; + space_or_comment0(input)?; + let goal = alt(( satisfy, optimize_bool, optimize_int, optimize_float, optimize_set, - ))(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, SolveItem { goal, annotations })) + )) + .parse_next(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(SolveItem { goal, annotations }) } #[derive(PartialEq, Clone, Debug)] @@ -60,89 +58,85 @@ pub enum OptimizationType { Maximize, } -pub fn satisfy<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Goal, E> { - let (input, _) = tag("satisfy")(input)?; - Ok((input, Goal::Satisfy)) +pub fn satisfy<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + tag("satisfy").parse_next(input)?; + Ok(Goal::Satisfy) } -fn opt_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, OptimizationType, E> { - alt((minimize, maximize))(input) +fn opt_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + alt((minimize, maximize)).parse_next(input) } -fn minimize<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, OptimizationType, E> { - let (input, _) = tag("minimize")(input)?; - Ok((input, OptimizationType::Minimize)) +fn minimize<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + tag("minimize").parse_next(input)?; + Ok(OptimizationType::Minimize) } -fn maximize<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, OptimizationType, E> { - let (input, _) = tag("maximize")(input)?; - Ok((input, OptimizationType::Maximize)) +fn maximize<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + tag("maximize").parse_next(input)?; + Ok(OptimizationType::Maximize) } -pub fn optimize_bool<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Goal, E> { - let (input, opt_type) = opt_type(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, be) = bool_expr(input)?; - Ok((input, Goal::OptimizeBool(opt_type, be))) +pub fn optimize_bool<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let opt_type = opt_type(input)?; + space_or_comment1(input)?; + let be = bool_expr(input)?; + Ok(Goal::OptimizeBool(opt_type, be)) } -pub fn optimize_int<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Goal, E> +pub fn optimize_int<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, opt_type) = opt_type(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, be) = int_expr(input)?; - Ok((input, Goal::OptimizeInt(opt_type, be))) + let opt_type = opt_type(input)?; + space_or_comment1(input)?; + let be = int_expr(input)?; + Ok(Goal::OptimizeInt(opt_type, be)) } -pub fn optimize_float<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Goal, E> +pub fn optimize_float<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, opt_type) = opt_type(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, be) = float_expr(input)?; - Ok((input, Goal::OptimizeFloat(opt_type, be))) + let opt_type = opt_type(input)?; + space_or_comment1(input)?; + let be = float_expr(input)?; + Ok(Goal::OptimizeFloat(opt_type, be)) } -pub fn optimize_set<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Goal, E> +pub fn optimize_set<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, opt_type) = opt_type(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, be) = set_expr(input)?; - Ok((input, Goal::OptimizeSet(opt_type, be))) + let opt_type = opt_type(input)?; + space_or_comment1(input)?; + let be = set_expr(input)?; + Ok(Goal::OptimizeSet(opt_type, be)) } #[test] fn test_solve_item() { use crate::solve_items::{Goal, OptimizationType}; use crate::{AnnExpr, Annotation, Expr}; - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "solve :: int_search(X_59,input_order,indomain_min,complete) minimize X_24;"; assert_eq!( - solve_item::>( - "solve :: int_search(X_59,input_order,indomain_min,complete) minimize X_24;" - ), - Ok(( - "", - SolveItem { - goal: Goal::OptimizeBool( - OptimizationType::Minimize, - BoolExpr::VarParIdentifier("X_24".to_string()) - ), - annotations: vec![Annotation { - id: "int_search".to_string(), - expressions: vec![ - AnnExpr::Expr(Expr::VarParIdentifier("X_59".to_string())), - AnnExpr::Expr(Expr::VarParIdentifier("input_order".to_string())), - AnnExpr::Expr(Expr::VarParIdentifier("indomain_min".to_string())), - AnnExpr::Expr(Expr::VarParIdentifier("complete".to_string())) - ] - }] - } - )) + solve_item::>(&mut input), + Ok(SolveItem { + goal: Goal::OptimizeBool( + OptimizationType::Minimize, + BoolExpr::VarParIdentifier("X_24".to_string()) + ), + annotations: vec![Annotation { + id: "int_search".to_string(), + expressions: vec![ + AnnExpr::Expr(Expr::VarParIdentifier("X_59".to_string())), + AnnExpr::Expr(Expr::VarParIdentifier("input_order".to_string())), + AnnExpr::Expr(Expr::VarParIdentifier("indomain_min".to_string())), + AnnExpr::Expr(Expr::VarParIdentifier("complete".to_string())) + ] + }] + }) ); } diff --git a/src/statements/mod.rs b/src/statements/mod.rs index 2412600..4cd25be 100644 --- a/src/statements/mod.rs +++ b/src/statements/mod.rs @@ -1,10 +1,7 @@ -use std::str; - -use nom::{ - branch::alt, - combinator::all_consuming, - error::{FromExternalError, ParseError}, - IResult, +use winnow::{ + combinator::{alt, eof}, + error::{FromExternalError, ParserError}, + PResult, Parser, }; use crate::{ @@ -29,63 +26,65 @@ pub enum Stmt { SolveItem(SolveItem), } -pub fn statement<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Stmt, E> +pub fn statement<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, res) = all_consuming(alt(( + let res = alt(( stmt_predicate, stmt_parameter, stmt_variable, stmt_constraint, stmt_solve_item, space_or_comment, - )))(input)?; - Ok((input, res)) + )) + .parse_next(input)?; + eof.parse_next(input)?; + Ok(res) } -fn stmt_predicate<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Stmt, E> +fn stmt_predicate<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, item) = predicate_declarations::predicate_item(input)?; - Ok((input, Stmt::Predicate(item))) + let item = predicate_declarations::predicate_item(input)?; + Ok(Stmt::Predicate(item)) } -fn stmt_parameter<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Stmt, E> +fn stmt_parameter<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, item) = parameter_declarations::par_decl_item(input)?; - Ok((input, Stmt::Parameter(item))) + let item = parameter_declarations::par_decl_item(input)?; + Ok(Stmt::Parameter(item)) } -fn stmt_variable<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Stmt, E> +fn stmt_variable<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, item) = variable_declarations::var_decl_item(input)?; - Ok((input, Stmt::Variable(item))) + let item = variable_declarations::var_decl_item(input)?; + Ok(Stmt::Variable(item)) } -fn stmt_constraint<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Stmt, E> +fn stmt_constraint<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, item) = constraint_item(input)?; - Ok((input, Stmt::Constraint(item))) + let item = constraint_item(input)?; + Ok(Stmt::Constraint(item)) } -fn stmt_solve_item<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Stmt, E> +fn stmt_solve_item<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, item) = solve_item(input)?; - Ok((input, Stmt::SolveItem(item))) + let item = solve_item(input)?; + Ok(Stmt::SolveItem(item)) } diff --git a/src/variables/declarations.rs b/src/variables/declarations.rs index b63e2ae..5caed1f 100644 --- a/src/variables/declarations.rs +++ b/src/variables/declarations.rs @@ -1,10 +1,7 @@ -use std::str; - -use nom::{ - character::complete::char, +use winnow::{ combinator::opt, - error::{FromExternalError, ParseError}, - IResult, + error::{FromExternalError, ParserError}, + PResult, Parser, }; use crate::{ @@ -140,219 +137,180 @@ pub enum VarDeclItem { }, } -pub fn var_decl_item<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, VarDeclItem, E> +pub fn var_decl_item<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = space_or_comment0(input)?; - let (input, item) = vdi_var(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(';')(input)?; - let (input, _) = space_or_comment0(input)?; - Ok((input, item)) + space_or_comment0(input)?; + let item = vdi_var(input)?; + space_or_comment0(input)?; + ';'.parse_next(input)?; + space_or_comment0(input)?; + Ok(item) } -fn vdi_var<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, VarDeclItem, E> +fn vdi_var<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, vt) = var_type(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(':')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, id) = var_par_identifier(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, annos) = annotations(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, assign) = opt(char('='))(input)?; + let vt = var_type(input)?; + space_or_comment0(input)?; + ':'.parse_next(input)?; + space_or_comment0(input)?; + let id = var_par_identifier(input)?; + space_or_comment0(input)?; + let annos = annotations(input)?; + space_or_comment0(input)?; + let assign = opt('=').parse_next(input)?; let assign = assign.is_some(); - let (input, _) = space_or_comment0(input)?; + space_or_comment0(input)?; match vt { VarType::BasicVarType(bvt) => match bvt { BasicVarType::BasicType(BasicType::Bool) => { - let (input, expr) = parse_rhs(assign, bool_expr, input)?; - Ok((input, VarDeclItem::Bool { id, annos, expr })) + let expr = parse_rhs(assign, bool_expr, input)?; + Ok(VarDeclItem::Bool { id, annos, expr }) } BasicVarType::BasicType(BasicType::Int) => { - let (input, expr) = parse_rhs(assign, int_expr, input)?; - Ok((input, VarDeclItem::Int { id, annos, expr })) + let expr = parse_rhs(assign, int_expr, input)?; + Ok(VarDeclItem::Int { id, annos, expr }) } BasicVarType::BasicType(BasicType::Float) => { - let (input, expr) = parse_rhs(assign, float_expr, input)?; - Ok((input, VarDeclItem::Float { id, annos, expr })) + let expr = parse_rhs(assign, float_expr, input)?; + Ok(VarDeclItem::Float { id, annos, expr }) } BasicVarType::IntInRange(lb, ub) => { - let (input, expr) = parse_rhs(assign, int_expr, input)?; - Ok(( - input, - VarDeclItem::IntInRange { - id, - lb, - ub, - expr, - annos, - }, - )) + let expr = parse_rhs(assign, int_expr, input)?; + Ok(VarDeclItem::IntInRange { + id, + lb, + ub, + expr, + annos, + }) } BasicVarType::IntInSet(set) => { - let (input, expr) = parse_rhs(assign, int_expr, input)?; - Ok(( - input, - VarDeclItem::IntInSet { - id, - set, - expr, - annos, - }, - )) + let expr = parse_rhs(assign, int_expr, input)?; + Ok(VarDeclItem::IntInSet { + id, + set, + expr, + annos, + }) } BasicVarType::BoundedFloat(lb, ub) => { - let (input, expr) = parse_rhs(assign, float_expr, input)?; - Ok(( - input, - VarDeclItem::BoundedFloat { - id, - lb, - ub, - expr, - annos, - }, - )) + let expr = parse_rhs(assign, float_expr, input)?; + Ok(VarDeclItem::BoundedFloat { + id, + lb, + ub, + expr, + annos, + }) } BasicVarType::SubSetOfIntRange(lb, ub) => { - let (input, expr) = parse_rhs(assign, set_expr, input)?; - Ok(( - input, - VarDeclItem::SubSetOfIntRange { - id, - lb, - ub, - expr, - annos, - }, - )) + let expr = parse_rhs(assign, set_expr, input)?; + Ok(VarDeclItem::SubSetOfIntRange { + id, + lb, + ub, + expr, + annos, + }) } BasicVarType::SubSetOfIntSet(set) => { - let (input, expr) = parse_rhs(assign, set_expr, input)?; - Ok(( - input, - VarDeclItem::SubSetOfIntSet { - id, - set, - expr, - annos, - }, - )) + let expr = parse_rhs(assign, set_expr, input)?; + Ok(VarDeclItem::SubSetOfIntSet { + id, + set, + expr, + annos, + }) } }, VarType::Array { ix, var_type } => match var_type { BasicVarType::BasicType(bt) => match bt { BasicType::Bool => { - let (input, array_expr) = parse_rhs(assign, array_of_bool_expr, input)?; - Ok(( - input, - VarDeclItem::ArrayOfBool { - ix, - id, - annos, - array_expr, - }, - )) - } - BasicType::Int => { - let (input, array_expr) = parse_rhs(assign, array_of_int_expr, input)?; - Ok(( - input, - VarDeclItem::ArrayOfInt { - ix, - id, - annos, - array_expr, - }, - )) - } - BasicType::Float => { - let (input, array_expr) = parse_rhs(assign, array_of_float_expr, input)?; - Ok(( - input, - VarDeclItem::ArrayOfFloat { - ix, - id, - annos, - array_expr, - }, - )) - } - }, - BasicVarType::IntInRange(lb, ub) => { - let (input, array_expr) = parse_rhs(assign, array_of_int_expr, input)?; - Ok(( - input, - VarDeclItem::ArrayOfIntInRange { - lb, - ub, + let array_expr = parse_rhs(assign, array_of_bool_expr, input)?; + Ok(VarDeclItem::ArrayOfBool { ix, id, annos, array_expr, - }, - )) - } - BasicVarType::IntInSet(set) => { - let (input, array_expr) = parse_rhs(assign, array_of_int_expr, input)?; - Ok(( - input, - VarDeclItem::ArrayOfIntInSet { - set, + }) + } + BasicType::Int => { + let array_expr = parse_rhs(assign, array_of_int_expr, input)?; + Ok(VarDeclItem::ArrayOfInt { ix, id, annos, array_expr, - }, - )) - } - BasicVarType::BoundedFloat(lb, ub) => { - let (input, array_expr) = parse_rhs(assign, array_of_float_expr, input)?; - Ok(( - input, - VarDeclItem::ArrayOfBoundedFloat { - lb, - ub, + }) + } + BasicType::Float => { + let array_expr = parse_rhs(assign, array_of_float_expr, input)?; + Ok(VarDeclItem::ArrayOfFloat { ix, id, annos, array_expr, - }, - )) + }) + } + }, + BasicVarType::IntInRange(lb, ub) => { + let array_expr = parse_rhs(assign, array_of_int_expr, input)?; + Ok(VarDeclItem::ArrayOfIntInRange { + lb, + ub, + ix, + id, + annos, + array_expr, + }) + } + BasicVarType::IntInSet(set) => { + let array_expr = parse_rhs(assign, array_of_int_expr, input)?; + Ok(VarDeclItem::ArrayOfIntInSet { + set, + ix, + id, + annos, + array_expr, + }) + } + BasicVarType::BoundedFloat(lb, ub) => { + let array_expr = parse_rhs(assign, array_of_float_expr, input)?; + Ok(VarDeclItem::ArrayOfBoundedFloat { + lb, + ub, + ix, + id, + annos, + array_expr, + }) } BasicVarType::SubSetOfIntRange(lb, ub) => { - let (input, array_expr) = parse_rhs(assign, array_of_set_expr, input)?; - Ok(( - input, - VarDeclItem::ArrayOfSubSetOfIntRange { - lb, - ub, - ix, - id, - annos, - array_expr, - }, - )) + let array_expr = parse_rhs(assign, array_of_set_expr, input)?; + Ok(VarDeclItem::ArrayOfSubSetOfIntRange { + lb, + ub, + ix, + id, + annos, + array_expr, + }) } BasicVarType::SubSetOfIntSet(set) => { - let (input, array_expr) = parse_rhs(assign, array_of_set_expr, input)?; - Ok(( - input, - VarDeclItem::ArrayOfSubSetOfIntSet { - set, - ix, - id, - annos, - array_expr, - }, - )) + let array_expr = parse_rhs(assign, array_of_set_expr, input)?; + Ok(VarDeclItem::ArrayOfSubSetOfIntSet { + set, + ix, + id, + annos, + array_expr, + }) } }, } @@ -361,147 +319,127 @@ where /// Parse the right hand side of a variable declaration if there is an assignment fn parse_rhs<'a, O, E>( assign: bool, - parser: impl Fn(&'a str) -> IResult<&'a str, O, E>, - input: &'a str, -) -> IResult<&'a str, Option, E> { + parser: impl Fn(&mut &'a str) -> PResult, + input: &mut &'a str, +) -> PResult, E> { Ok(if assign { - let (input, expr) = parser(input)?; - (input, Some(expr)) + let expr = parser(input)?; + Some(expr) } else { - (input, None) + None }) } #[test] fn test_var_decl_item_1() { use crate::{AnnExpr, Annotation, ArrayOfSetExpr, Expr, IntExpr, SetExpr, SetLiteralExpr}; - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "array [1..1] of var set of 1..10: sets:: output_array([1..1]) = [X_0];"; assert_eq!( - var_decl_item::>( - "array [1..1] of var set of 1..10: sets:: output_array([1..1]) = [X_0];" - ), - Ok(( - "", - VarDeclItem::ArrayOfSubSetOfIntRange { - ix: IndexSet(1), - id: "sets".to_string(), - annos: vec![Annotation { - id: "output_array".to_string(), - expressions: vec![AnnExpr::Expr(Expr::ArrayOfSet(vec![SetExpr::Set( - SetLiteralExpr::IntInRange(IntExpr::Int(1), IntExpr::Int(1)) - )]))] - }], - lb: 1, - ub: 10, - array_expr: Some(ArrayOfSetExpr::Array(vec![SetExpr::VarParIdentifier( - "X_0".to_owned() - )])) - } - )) + var_decl_item::>(&mut input), + Ok(VarDeclItem::ArrayOfSubSetOfIntRange { + ix: IndexSet(1), + id: "sets".to_string(), + annos: vec![Annotation { + id: "output_array".to_string(), + expressions: vec![AnnExpr::Expr(Expr::ArrayOfSet(vec![SetExpr::Set( + SetLiteralExpr::IntInRange(IntExpr::Int(1), IntExpr::Int(1)) + )]))] + }], + lb: 1, + ub: 10, + array_expr: Some(ArrayOfSetExpr::Array(vec![SetExpr::VarParIdentifier( + "X_0".to_owned() + )])) + }) ); } - #[test] fn test_var_decl_item_2() { - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "array [1..5] of var 0..3: w =X_32;"; assert_eq!( - var_decl_item::>("array [1..5] of var 0..3: w =X_32;"), - Ok(( - "", - VarDeclItem::ArrayOfIntInRange { - id: "w".to_string(), - ix: IndexSet(5), - lb: 0, - ub: 3, - array_expr: Some(ArrayOfIntExpr::VarParIdentifier("X_32".to_string())), - annos: vec![], - } - )) + var_decl_item::>(&mut input), + Ok(VarDeclItem::ArrayOfIntInRange { + id: "w".to_string(), + ix: IndexSet(5), + lb: 0, + ub: 3, + array_expr: Some(ArrayOfIntExpr::VarParIdentifier("X_32".to_string())), + annos: vec![], + }) ); } - #[test] fn test_var_decl_item_3() { - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "array [1..5] of var {1,2,3}: w;"; assert_eq!( - var_decl_item::>("array [1..5] of var {1,2,3}: w;"), - Ok(( - "", - VarDeclItem::ArrayOfIntInSet { - id: "w".to_string(), - ix: IndexSet(5), - set: vec![1, 2, 3], - array_expr: None, - annos: vec![], - } - )) + var_decl_item::>(&mut input), + Ok(VarDeclItem::ArrayOfIntInSet { + id: "w".to_string(), + ix: IndexSet(5), + set: vec![1, 2, 3], + array_expr: None, + annos: vec![], + }) ); } - #[test] fn test_var_decl_item_4() { use crate::Annotation; - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "array [1..5] of var 0..3: w;"; assert_eq!( - var_decl_item::>("array [1..5] of var 0..3: w;"), - Ok(( - "", - VarDeclItem::ArrayOfIntInRange { - id: "w".to_string(), - ix: IndexSet(5), - lb: 0, - ub: 3, - array_expr: None, - annos: vec![], - } - )) + var_decl_item::>(&mut input), + Ok(VarDeclItem::ArrayOfIntInRange { + id: "w".to_string(), + ix: IndexSet(5), + lb: 0, + ub: 3, + array_expr: None, + annos: vec![], + }) ); + let mut input = "var 1..101: objective :: output_var = X_2586;"; assert_eq!( - var_decl_item::>("var 1..101: objective :: output_var = X_2586;"), - Ok(( - "", - VarDeclItem::IntInRange { - id: "objective".to_string(), - lb: 1, - ub: 101, - expr: Some(IntExpr::VarParIdentifier("X_2586".to_string())), - annos: vec![Annotation { - id: "output_var".to_string(), - expressions: vec![] - }], - } - )) + var_decl_item::>(&mut input), + Ok(VarDeclItem::IntInRange { + id: "objective".to_string(), + lb: 1, + ub: 101, + expr: Some(IntExpr::VarParIdentifier("X_2586".to_string())), + annos: vec![Annotation { + id: "output_var".to_string(), + expressions: vec![] + }], + }) ); } - #[test] fn test_var_decl_item_5() { use crate::{ArrayOfSetExpr, SetExpr, SetLiteralExpr}; - use nom::error::VerboseError; + use winnow::error::ContextError; + let mut input = "array [1..3] of var set of 17..42: h = [{42,17},23..X,{}];"; assert_eq!( - var_decl_item::>( - "array [1..3] of var set of 17..42: h = [{42,17},23..X,{}];" - ), - Ok(( - "", - VarDeclItem::ArrayOfSubSetOfIntRange { - lb: 17, - ub: 42, - annos: vec![], - ix: IndexSet(3), - id: "h".to_string(), - array_expr: Some(ArrayOfSetExpr::Array(vec![ - SetExpr::Set(SetLiteralExpr::SetInts(vec![ - IntExpr::Int(42), - IntExpr::Int(17) - ])), - SetExpr::Set(SetLiteralExpr::IntInRange( - IntExpr::Int(23), - IntExpr::VarParIdentifier("X".to_string()) - )), - SetExpr::Set(SetLiteralExpr::SetInts(vec![])), + var_decl_item::>(&mut input), + Ok(VarDeclItem::ArrayOfSubSetOfIntRange { + lb: 17, + ub: 42, + annos: vec![], + ix: IndexSet(3), + id: "h".to_string(), + array_expr: Some(ArrayOfSetExpr::Array(vec![ + SetExpr::Set(SetLiteralExpr::SetInts(vec![ + IntExpr::Int(42), + IntExpr::Int(17) ])), - } - )) + SetExpr::Set(SetLiteralExpr::IntInRange( + IntExpr::Int(23), + IntExpr::VarParIdentifier("X".to_string()) + )), + SetExpr::Set(SetLiteralExpr::SetInts(vec![])), + ])), + }) ); } diff --git a/src/variables/types.rs b/src/variables/types.rs index e7ed52d..2b11f00 100644 --- a/src/variables/types.rs +++ b/src/variables/types.rs @@ -1,12 +1,9 @@ -use std::str; - -use nom::{ - branch::alt, - bytes::complete::tag, - character::complete::char, - error::{FromExternalError, ParseError}, - multi::separated_list0, - IResult, +use winnow::{ + combinator::alt, + combinator::separated0, + error::{FromExternalError, ParserError}, + token::tag, + PResult, Parser, }; use crate::{ @@ -24,41 +21,40 @@ pub enum VarType { }, } -pub fn var_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, VarType, E> +pub fn var_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, var_type) = alt((vt_basic_var_type, array_var_type))(input)?; - Ok((input, var_type)) + alt((vt_basic_var_type, array_var_type)).parse_next(input) } -fn vt_basic_var_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, VarType, E> +fn vt_basic_var_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, vt) = basic_var_type(input)?; - Ok((input, VarType::BasicVarType(vt))) + let vt = basic_var_type(input)?; + Ok(VarType::BasicVarType(vt)) } -fn array_var_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, VarType, E> +fn array_var_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = tag("array")(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char('[')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ix) = index_set(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char(']')(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _tag) = tag("of")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, var_type) = basic_var_type(input)?; - Ok((input, VarType::Array { ix, var_type })) + tag("array").parse_next(input)?; + space_or_comment0(input)?; + '['.parse_next(input)?; + space_or_comment0(input)?; + let ix = index_set(input)?; + space_or_comment0(input)?; + ']'.parse_next(input)?; + space_or_comment1(input)?; + tag("of").parse_next(input)?; + space_or_comment1(input)?; + let var_type = basic_var_type(input)?; + Ok(VarType::Array { ix, var_type }) } #[derive(PartialEq, Clone, Debug)] @@ -71,158 +67,153 @@ pub enum BasicVarType { SubSetOfIntRange(i128, i128), } -pub fn basic_var_type<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicVarType, E> +pub fn basic_var_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError> + FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("var")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, vt) = alt(( + space_or_comment0(input)?; + tag("var").parse_next(input)?; + space_or_comment1(input)?; + let vt = alt(( bvt_basic_type, bvt_int_in_range, bvt_int_in_set, bvt_bounded_float, bvt_subset_of_int_set, bvt_subset_of_int_range, - ))(input)?; - Ok((input, vt)) + )) + .parse_next(input)?; + Ok(vt) } -fn bvt_basic_type<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BasicVarType, E> { - let (input, bt) = basic_type(input)?; - Ok((input, BasicVarType::BasicType(bt))) +fn bvt_basic_type<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult { + let bt = basic_type(input)?; + Ok(BasicVarType::BasicType(bt)) } -fn bvt_int_in_range<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BasicVarType, E> +fn bvt_int_in_range<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, (lb, ub)) = int_in_range(input)?; - Ok((input, BasicVarType::IntInRange(lb, ub))) + let (lb, ub) = int_in_range(input)?; + Ok(BasicVarType::IntInRange(lb, ub)) } -fn bvt_int_in_set<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, BasicVarType, E> +fn bvt_int_in_set<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, set) = int_in_set(input)?; - Ok((input, BasicVarType::IntInSet(set))) + let set = int_in_set(input)?; + Ok(BasicVarType::IntInSet(set)) } -fn bvt_bounded_float<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicVarType, E> +fn bvt_bounded_float<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, (lb, ub)) = bounded_float(input)?; - Ok((input, BasicVarType::BoundedFloat(lb, ub))) + let (lb, ub) = bounded_float(input)?; + Ok(BasicVarType::BoundedFloat(lb, ub)) } -fn bvt_subset_of_int_range<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicVarType, E> +fn bvt_subset_of_int_range<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, (lb, ub)) = subset_of_int_range(input)?; - Ok((input, BasicVarType::SubSetOfIntRange(lb, ub))) + let (lb, ub) = subset_of_int_range(input)?; + Ok(BasicVarType::SubSetOfIntRange(lb, ub)) } -fn bvt_subset_of_int_set<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, BasicVarType, E> +fn bvt_subset_of_int_set<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, set) = subset_of_int_set(input)?; - Ok((input, BasicVarType::SubSetOfIntSet(set))) + let set = subset_of_int_set(input)?; + Ok(BasicVarType::SubSetOfIntSet(set)) } -pub fn int_in_range<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, (i128, i128), E> +pub fn int_in_range<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<(i128, i128), E> where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, lb) = int_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("..")(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ub) = int_literal(input)?; - Ok((input, (lb, ub))) + let lb = int_literal(input)?; + space_or_comment0(input)?; + tag("..").parse_next(input)?; + space_or_comment0(input)?; + let ub = int_literal(input)?; + Ok((lb, ub)) } -pub fn bounded_float<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, (f64, f64), E> +pub fn bounded_float<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<(f64, f64), E> where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, lb) = float_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("..")(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ub) = float_literal(input)?; - Ok((input, (lb, ub))) + let lb = float_literal(input)?; + space_or_comment0(input)?; + tag("..").parse_next(input)?; + space_or_comment0(input)?; + let ub = float_literal(input)?; + Ok((lb, ub)) } // "{" "," ... "}" -pub fn float_in_set<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Vec, E> +pub fn float_in_set<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult, E> where E: FromExternalError<&'a str, std::num::ParseFloatError>, { - let (input, _) = char('{')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), float_literal)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char('}')(input)?; - Ok((input, v)) + '{'.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(float_literal, ',').parse_next(input)?; + space_or_comment0(input)?; + '}'.parse_next(input)?; + Ok(v) } // "set" "of" ".." -pub fn subset_of_int_range<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, (i128, i128), E> +pub fn subset_of_int_range<'a, E: ParserError<&'a str>>( + input: &mut &'a str, +) -> PResult<(i128, i128), E> where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _tag) = tag("set")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, _tag) = tag("of")(input)?; - let (input, _) = space_or_comment1(input)?; - let (input, lb) = int_literal(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("..")(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, ub) = int_literal(input)?; - Ok((input, (lb, ub))) + tag("set").parse_next(input)?; + space_or_comment1(input)?; + tag("of").parse_next(input)?; + space_or_comment1(input)?; + let lb = int_literal(input)?; + space_or_comment0(input)?; + tag("..").parse_next(input)?; + space_or_comment0(input)?; + let ub = int_literal(input)?; + Ok((lb, ub)) } // "set" "of" "{" [ "," ... ] "}" -pub fn subset_of_int_set<'a, E: ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Vec, E> +pub fn subset_of_int_set<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult, E> where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _tag) = tag("set of {")(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), int_literal)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _tag) = tag("}")(input)?; - Ok((input, v)) + tag("set of {").parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(int_literal, ',').parse_next(input)?; + space_or_comment0(input)?; + tag("}").parse_next(input)?; + Ok(v) } // "{" "," ... "}" -pub fn int_in_set<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Vec, E> +pub fn int_in_set<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult, E> where E: FromExternalError<&'a str, std::num::ParseIntError>, { - let (input, _) = char('{')(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, v) = separated_list0(char(','), int_literal)(input)?; - let (input, _) = space_or_comment0(input)?; - let (input, _) = char('}')(input)?; - Ok((input, v)) + '{'.parse_next(input)?; + space_or_comment0(input)?; + let v = separated0(int_literal, ',').parse_next(input)?; + space_or_comment0(input)?; + '}'.parse_next(input)?; + Ok(v) }