Rust中nom库将解析错误转为Ok结果的惯用方法是什么?
使用nom解析C风格单行注释的优雅实现方式
需求与现有问题
需要解析C风格的单行注释(格式为// some comment,从//开始到换行符结束),待解析文本的每行右侧可能包含这类注释。
现有解析函数在存在注释时可以正常工作,但无注释时会返回错误:
pub fn parse_single_line_comments(i: &str) -> IResult<&str, &str> { recognize(pair(tag("//"), is_not("\n\r")))(i) }
为了让无注释时返回空字符串,最初用match匹配返回值的写法不够优雅:
pub fn parse_single_line_comments(i: &str) -> IResult<&str, &str> { match recognize(pair(tag("//"), is_not("\n\r")))(i) { Ok((rest, comment)) => Ok((rest, comment)), _ => Ok((i, "")), } }
惯用的nom实现方式
nom提供了opt组合子专门处理可选解析的场景,配合map组合子可以优雅地实现需求:
use nom::{ combinator::{opt, recognize, map}, sequence::pair, bytes::complete::{tag, is_not}, IResult, }; pub fn parse_single_line_comments(i: &str) -> IResult<&str, &str> { map( // 使用opt包裹原解析器,将其转为可选解析 opt(recognize(pair(tag("//"), is_not("\n\r")))), // 将Option<&str>转换为&str,None时返回空字符串 |opt_comment| opt_comment.unwrap_or("") )(i) }
说明
opt组合子:尝试执行内部的解析器,成功则返回Some(解析结果),失败则返回None,且始终返回Ok状态(不会触发解析错误)map组合子:将opt返回的Option<&str>转换为目标类型&str,用unwrap_or("")处理无注释的情况- 如果后续需要改为返回
Option<&str>类型,只需去掉map层,让函数返回IResult<&str, Option<&str>>即可,灵活性更高
内容的提问来源于stack exchange,提问作者exocortex
相关产品推荐
相关产品推荐

