如何使用 nom 将带符号的字符串解析为 i32?

Nic*_*s C 5 parsing rust nom

使用nom crate,我正在尝试编写一个解析器,它可以i32从 a 中识别有符号数String,即可以将字符串-42转换为i32表示形式。

到目前为止,我想出了以下内容,但我无法解析负数:

use nom::types::CompleteStr;
use std::str::FromStr;

named!(
    i32_parser<CompleteStr, i32>,
    map_res!(nom::digit, |CompleteStr(s)| i32::from_str(s))
);

#[test]
fn parse_i32_positive() {
    assert_eq!(
        i32_parser(CompleteStr::from("42")),
        Ok((CompleteStr::from(""), 42))
    );
}

#[test]
fn parse_i32_negative() {
    assert_eq!(
        i32_parser(CompleteStr::from("-42")),
        Ok((CompleteStr::from(""), -42))
    );
}
Run Code Online (Sandbox Code Playgroud)

我也试过以下,但有一个神秘的编译错误:

use nom::types::CompleteStr;
use std::str::FromStr;

named!(
    i32_parser<CompleteStr, i32>,
    map_res!(nom::digit, |CompleteStr(s)| i32::from_str(s))
);

#[test]
fn parse_i32_positive() {
    assert_eq!(
        i32_parser(CompleteStr::from("42")),
        Ok((CompleteStr::from(""), 42))
    );
}

#[test]
fn parse_i32_negative() {
    assert_eq!(
        i32_parser(CompleteStr::from("-42")),
        Ok((CompleteStr::from(""), -42))
    );
}
Run Code Online (Sandbox Code Playgroud)

关于如何修复它的任何建议?或者用 nom 实现这一目标的更简单方法?

我明确地希望用 nom 来实现这个,因为我试图解析一个更复杂的结构。i32::from_str(s)适用于简单的字符串,但这不是我要找的。

sta*_*lue 5

recognize!宏可以帮助你。它返回解析后的输入字符串而不是解析器输出,然后可以像往常一样进行转换。例如:

named!(i32_parser<&str, i32>,
    map_res!(
        recognize!(tuple!(opt!(char!('-')), digit)),
        FromStr::from_str)
);
Run Code Online (Sandbox Code Playgroud)


Alp*_*per 5

更新了现代非宏名词:

fn parse_isize(input: &str) -> IResult<&str, isize> {
    let (i, number) = map_res(recognize(preceded(opt(tag("-")), digit1)), |s| {
        isize::from_str(s)
    })(input)?;

    Ok((i, number))
}
Run Code Online (Sandbox Code Playgroud)