Skip to content

Commit

Permalink
Port to winnow
Browse files Browse the repository at this point in the history
  • Loading branch information
sthiele committed Oct 26, 2023
1 parent 0c2fda0 commit eab6db5
Show file tree
Hide file tree
Showing 19 changed files with 1,449 additions and 1,598 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
Expand Down
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,19 @@ In your Cargo.toml

```toml
[dependencies]
flatzinc = "0.3"
flatzinc = "0.3.20-dev"
```

In your code:

```rust
use flatzinc::*;

match flatzinc::model::<VerboseError<&str>>(&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::<ContextError<&str>>(&buf) {
Ok(result) => println!("{:#?}", result),
Err(e) => {
error!("Failed to parse flatzinc!\n{}", e)
}
Err(e) => println!("Failed to parse flatzinc: {:?}", e),
}
```

Expand Down
17 changes: 6 additions & 11 deletions examples/fz-parser.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand All @@ -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::<VerboseError<&str>>(&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::<ContextError<&str>>(&mut line) {
Ok(result) => println!("{:#?}", result),
Err(e) => {
error!("Failed to parse flatzinc!\n{}", e)
}
Err(e) => error!("Failed to parse flatzinc: {:?}", e),
}
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.3"
nom = "7.0.0"
winnow = "=0.5.16"

[dependencies.flatzinc]
path = ".."
Expand Down
18 changes: 5 additions & 13 deletions fuzz/fuzz_targets/fuzz_target_1.rs
Original file line number Diff line number Diff line change
@@ -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::<VerboseError<&str>>(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::<ContextError<&str>>(&mut utf8_str) {
Ok(result) => println!("{:#?}", result),
Err(e) => print!("Failed to parse flatzinc: {:?}", e),
}
} else {
Expand Down
28 changes: 13 additions & 15 deletions src/basic_types.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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<BasicType, E> {
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<BasicType, E> {
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<BasicType, E> {
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<BasicType, E> {
tag("float").parse_next(input)?;
Ok(BasicType::Float)
}
56 changes: 24 additions & 32 deletions src/comments.rs
Original file line number Diff line number Diff line change
@@ -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::<VerboseError<&str>>("% Comments can have anyth!ng in it really <3"),
Ok(("", " Comments can have anyth!ng in it really <3".into()))
comment::<ContextError<&str>>(&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<Stmt, E> {
let s = space_or_comment0(input)?;
Ok(Stmt::Comment(s.into()))
}
Loading

0 comments on commit eab6db5

Please sign in to comment.