首页 > 其他分享 >nom::sequence::preceded Matches an object from the first parser and discards it, then gets an object

nom::sequence::preceded Matches an object from the first parser and discards it, then gets an object

时间:2024-12-27 16:56:10浏览次数:9  
标签:nom preceded 符号 parser Token let Integer64 input

nom::sequence::preceded
Matches an object from the first parser and discards it, then gets an object from the second parser.
上面是rust nom官网对于preceded的解释

UUUUUUUUU
你完全正确,nom::sequence::preceded 的定义确实是:

Matches an object from the first parser and discards it, then gets an object from the second parser.

这意味着 preceded 会先运行第一个解析器来匹配输入,成功后丢弃第一个解析器的结果,然后继续执行第二个解析器并返回第二个解析器的结果。

在你提供的代码中,使用 preceded 时:

let parse_number = preceded(
    opt(alt((char('+'), char('-')))), // 可选的 + 或 - 符号
    digit1, // 至少一个数字
);

preceded 中的两个解析器分别是:

  1. 第一个解析器opt(alt((char('+'), char('-')))),用于匹配一个可选的符号 +-opt 表示这个符号是可选的,alt 表示匹配 +- 中的一个。
  2. 第二个解析器digit1,用于匹配至少一个数字。

这里,preceded 会先尝试匹配一个符号(+-),然后继续匹配至少一个数字。第一个解析器的结果(符号)会被丢弃,最终返回第二个解析器(数字)解析的结果。

如果需要修改函数使其同时返回符号信息(是否为负数),可以将符号部分的匹配改为通过其他方式返回,例如 altopt 组合时,可以让符号作为返回值之一。

修改代码的正确方式:

为了正确地获取符号信息,并且返回 bool 类型的变量,我们需要对符号部分进行修改,而不是完全依赖 preceded。我会改用一个更加合适的解析方式。

解决方案:

use nom::{
    character::complete::{digit1, char},
    combinator::{map, opt},
    sequence::preceded,
    IResult,
};

// Token 枚举
#[derive(Debug, PartialEq)]
pub enum Token {
    Integer64(i64),
    // 其他Token类型
}

// 解析带符号或不带符号的整数
fn integer64(input: &str) -> IResult<&str, (Token, bool)> {
    // 判断第一个字符是否为 '-',并设置 bool 类型变量
    let is_negative = input.chars().next() == Some('-');

    // 允许 + 或 - 符号,后接至少一个数字
    let parse_number = alt((
        map(preceded(char('-'), digit1), |s: &str| Token::Integer64(s.parse().unwrap())),
        map(preceded(char('+'), digit1), |s: &str| Token::Integer64(s.parse().unwrap())),
        map(digit1, |s: &str| Token::Integer64(s.parse().unwrap())),
    ));

    let result = parse_number(input);

    result.map(|(next_input, token)| {
        (next_input, (token, is_negative))
    })
}

fn main() {
    let input = "-123";
    let result = integer64(input);
    match result {
        Ok((next_input, (token, is_negative))) => {
            println!("Parsed token: {:?}, Is Negative: {}", token, is_negative);
        }
        Err(_) => {
            println!("Parsing failed");
        }
    }
}

解析逻辑解释:

  • 我们修改了符号部分的解析,使其直接返回符号信息和数值部分。
  • 使用 alt 来处理:
    • 如果符号是 "-",则通过 preceded(char('-'), digit1) 解析。
    • 如果符号是 "+",则通过 preceded(char('+'), digit1) 解析。
    • 如果没有符号,则直接通过 digit1 解析。
  • 解析后,直接返回数值和符号的标记元组 (Token::Integer64(i64), bool),表示数字和是否为负数。

测试:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_integer64() {
        let inputs = vec![
            ("123", (Token::Integer64(123), false)),
            ("-123", (Token::Integer64(-123), true)),
            ("+123", (Token::Integer64(123), false)),
            ("0", (Token::Integer64(0), false)),
        ];

        for (input, expected) in inputs {
            let result = integer64(input);
            assert!(result.is_ok());
            let (_, (token, is_negative)) = result.unwrap();
            assert_eq!(token, expected.0);
            assert_eq!(is_negative, expected.1);
        }
    }

    #[test]
    fn test_invalid_integer64() {
        let inputs = vec![
            "123abc", // 非法的数字
            "-abc",   // 非法的数字
            "+",      // 没有数字
        ];

        for input in inputs {
            let result = integer64(input);
            assert!(result.is_err());
        }
    }
}

总结:

  • preceded 是用于匹配前一个部分并丢弃结果的。如果要同时获取符号信息,可以在解析符号时单独处理,并将符号作为返回值的一部分。
  • 使用 altpreceded 更灵活地处理符号,并同时获取符号信息和数值。

标签:nom,preceded,符号,parser,Token,let,Integer64,input
From: https://www.cnblogs.com/Tifahfyf/p/18636160

相关文章

  • OmniParser,微软的用于纯视觉 GUI 分析的Agent
    OmniParser是微软最近发布的一个解析界面的库,主要将成果解析后转送给大模型体系进行更多的能力拓展。等于是将传统的UI界面,转换成了LLM大模型语言等Agent系统能直接理解和处理的输入源了。非常有意思。用官方的话来说:OmniParser是一种将用户界面截图解析为结构化、易于理解......
  • 波折重重:Linux实时系统Xenomai宕机问题的深度定位
    目录一前言二背景三原因分析及措施硬件原因应用软件操作系统四分析定位转机拨云见雾irq计数Schedstatcoreclk现象结论五原因一六原因二七解决八结语一前言在上一篇博文中,我们详细介绍了Xenomai的看门狗机制。本文将带您深入了解一个与之相关的真实事故现场及其问题定位......
  • Application run failed .ParserException: while parsing a block mapping in 'reade
    [root@ecm-8cc1logs]#tail-f-n1000sys-error.log17:26:46.060[main]ERRORo.s.b.SpringApplication-[reportFailure,870]-Applicationrunfailedorg.yaml.snakeyaml.parser.ParserException:whileparsingablockmappingin'reader',line2,col......
  • Economic-Statistics-Experiment-Design&Analysis-: 统计: 试验设计与分析: 5 Free Re
    Economic-Statistics-Experiment-Design&Analysis-:5FreeResourcesforLearningExperimentalDesigninStatisticsbyVinodChuganiPostedonAugust26,2024Experimentaldesignisafundamentalcomponentofstatisticalanalysis,enablingresearchersto......
  • OmniParser:快速识别 UI 截图转换为结构化数据
    OmniParser是微软开发的一个用于解析用户界面(UI)截图的工具,旨在将这些截图转换为结构化数据。这个工具的主要目标是提升大型语言模型(如GPT-4V)与图形用户界面的互动能力。它能够识别截图中可交互的元素(如图标和按钮),并理解这些元素的语义,以便生成相应的操作指令。OmniParser由两个......
  • 【原创】xenomai环境下开源实时数控系统LinuxCNC编译安装
    linuxcnc在xenomai下的构建简单记录,参考链接https://www.linuxcnc.org/docs/devel/html/code/building-linuxcnc.html1.环境软硬件环境桌面环境:Ubuntu24.04+xenomai3.3硬件:rk3588(nanoPiR6/T6)对xenomai内核要求要在使linuxcnc在xenomai上运行,内核配置Localversion必须是-......
  • 用pandas读取MRPC数据库时报错:pandas.errors.ParserError: Error tokenizing data. C
    读取的代码很简单,如下:data_path='MRPC/msr_paraphrase_test.txt'df=pd.read_csv(data_path,sep='\t',encoding='utf-8')困扰了一下午,最后本来不打算解决了。想着直接跳过错误,即:df=pd.read_csv(data_path,sep='\t',encoding='utf-8',on_......
  • 「ABC245D」 Polynomial division
    题意给定多项式\(A\)和\(C\),求\(C\)除以\(A\)的结果\(B\)。分析先考虑用\(a_i\)和\(b_j\)表示\(c_{i+j}\),多项式乘法的朴素方法是把两式的每一位都乘起来,最后相加。具体形式为\[\begin{array}{c}c_{n+m}=a_{n}b_{m}\\c_{n+m-1}=a_{n}b_{m-1}+a_{n-1}b_{m}\\c......
  • 5.3.2 Xenomai3:使用xeno-config获取编译和链接参数
    点击查看系列文章=》 InterruptPipeline系列文章大纲-CSDN博客原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!5.3.2Xenomai3:使用xeno-config获取编译和链接参数xeno-config是一个辅助脚本,用于为使用Xenomai库的应用程序提供正确的编译和链接标志。通过......
  • 5.3.1 Xenomai3:libcobalt库和API/Skin分析
    点击查看系列文章=》 InterruptPipeline系列文章大纲-CSDN博客原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!5.3Xenomai进程和线程的创建5.3.1Xenomai3:libcobalt库和API/Skin分析结合官方网址Overview::Xenomai3的一章图来分析。里面的颜色和文......