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

Parsing 如何使用nom将带符号的字符串解析为i32?,parsing,rust,nom,Parsing,Rust,Nom,使用这个板条箱,我试图编写一个解析器,它可以从字符串中识别有符号的i32数字,也就是说,可以将字符串-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)) )

使用这个板条箱,我试图编写一个解析器,它可以从
字符串中识别有符号的
i32
数字,也就是说,可以将字符串
-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))
    );
}
使用nom::types::CompleteStr;
使用std::str::FromStr;
命名!(
i32_解析器,
地图(名称::数字,| CompleteStr(s)| i32::来自| str(s))
);
#[测试]
fn parse_i32_positive(){
断言(
i32_解析器(CompleteStr::from(“42”)),
Ok((CompleteStr::from(“”,42))
);
}
#[测试]
fn parse_i32_negative(){
断言(
i32_解析器(CompleteStr::from(“-42”),
Ok((CompleteStr::from(“”,-42))
);
}
我还尝试了以下操作,但出现了一个神秘的编译错误:

命名!(
i32_解析器,
map_res!(alt!(char!('-')| nom::digit),| CompleteStr(s)| i32::from_str(s))
);
^应为字符,找到结构`nom::types::CompleteStr`
有没有关于如何修复的建议?还是使用nom实现这一点的更简单方法

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

alt!(char!('-')|nom::digit)
返回一个char,因此lambda需要接受一个char作为参数。而且它可能是
'-'
,因此在运行时对其调用
i32::from_str
将失败

不要在一个步骤中同时处理符号和数字,而应该将问题分解为两部分,例如使用
do_parse

named!(
    i32_parser<CompleteStr, i32>,
    do_parse!(
        minus: opt!(char!('-')) >>
        digits: many1!(digit) >>
        ({
            let sign = if minus.is_some() { -1 } else { 1 };
            let mut number = 0;
            for digit in digits {
                number = number*10 + i32::from_str(digit.0).unwrap();
            }
            sign * number
        })
    )
);
命名!(
i32_解析器,
别客气(
减:opt!(char!('-')>>
数字:多个!(数字)>>
({
设sign=if减号.is_some(){-1}else{1};
设mut数=0;
数字中的数字{
number=number*10+i32::from_str(数字0).unwrap();
}
符号*数字
})
)
);

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

named!(i32_parser<&str, i32>,
    map_res!(
        recognize!(tuple!(opt!(char!('-')), digit)),
        FromStr::from_str)
);
命名!(i32_解析器,
地图(
识别!(元组!(选项!(字符!('-')),数字)),
FromStr::FromStr)
);

“alt!(char!('-')| nom::digit)“返回”一个char,因此您的lambda需要接受一个char作为参数。它可能是'-',因此在运行时从其上调用i32::将会失败。”,代码将无法编译,您的意思是什么?rust是一种强类型语言。只需使用nom中的
take_,而
combinator,这段代码就不会“在运行时失败”,这不是有点奇怪吗?有这么多函数来解析数字,但没有像这样基本的东西?