完成这个函数,解析带符号或不带符号的整形
fn integer64(input: &str) -> IResult<&str, Token> {
// map(digit1, |s: &str| Token::Number(s.parse().unwrap()))(input)
}
完成这个函数,解析带符号或不带符号的整形
UUUUUUUUUUUUUUUUUUUUUUU
为了完成 integer64 函数并解析带符号或不带符号的 64 位整数,我们需要使用 nom 提供的字符处理和组合器来处理符号(如 + 或 -)以及数字部分。
我们可以按以下步骤进行:
- 允许可选的符号(
+或-),如果没有符号,默认是正数。 - 解析数字部分,确保它是有效的 64 位整数。
- 返回解析后的
Token::Number,将解析的字符串转换为i64。
代码实现
use nom::{
character::complete::{digit1, char},
combinator::{map, opt},
IResult,
sequence::preceded,
};
// Token 枚举类型
#[derive(Debug, PartialEq)]
pub enum Token {
Number(i64),
// 其他Token类型
}
// 解析带符号或不带符号的整数
fn integer64(input: &str) -> IResult<&str, Token> {
// 允许 + 或 - 符号,后接至少一个数字
let parse_number = preceded(
opt(alt((char('+'), char('-')))), // 可选的 + 或 - 符号
digit1, // 至少一个数字
);
map(parse_number, |s: &str| Token::Number(s.parse().unwrap()))(input)
}
// 测试
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_integer64() {
let inputs = vec![
("123", Token::Number(123)),
("-123", Token::Number(-123)),
("+123", Token::Number(123)),
("0", Token::Number(0)),
];
for (input, expected) in inputs {
let result = integer64(input);
assert!(result.is_ok());
let token = result.unwrap().1;
assert_eq!(token, expected);
}
}
#[test]
fn test_invalid_integer64() {
let inputs = vec![
"123abc", // 非法的数字
"-abc", // 非法的数字
"+", // 没有数字
];
for input in inputs {
let result = integer64(input);
assert!(result.is_err());
}
}
}
解释:
-
preceded和opt:preceded用于匹配符号(如果有的话),然后是至少一个数字(digit1)。opt(alt((char('+'), char('-'))))用来匹配+或-符号,但它们是可选的。
-
digit1:digit1会匹配至少一个数字字符。如果遇到连续的数字字符,它将返回一个字符串切片(&str)。
-
map:- 使用
map把匹配到的数字字符串(例如"123")解析成i64类型,并封装为Token::Number枚举。
- 使用
-
测试用例:
test_integer64:测试带符号和不带符号的整数解析。test_invalid_integer64:测试无效的整数(例如带有非数字字符的输入)。
测试输出:
123->Token::Number(123)-123->Token::Number(-123)+123->Token::Number(123)0->Token::Number(0)
无效输入如 "123abc" 或 "+abc" 会导致解析失败,返回错误。
运行测试:
你可以通过运行 cargo test 来验证这个实现。
浙公网安备 33010602011771号