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
来验证这个实现。
来源链接:https://www.cnblogs.com/Tifahfyf/p/18635646
没有回复内容