【问题标题】:Parsing a variably space delimited list with nom用 nom 解析可变空格分隔的列表
【发布时间】:2021-04-23 20:31:47
【问题描述】:

如何使用可能由空格分隔或不分隔的令牌列表?

我正在尝试使用nom (6.1.2) 解析cedict 格式的中文罗马拼音(拼音)。例如"ni3 hao3 ma5",由于人为抄写错误,有时写为"ni3hao3ma5""ni3hao3 ma5"(注意可变间距)。

我编写了一个解析器来处理单个音节,例如["ni3", "hao3", "ma5"],我正在尝试使用 nom::multi::separated_list0 来解析它:

nom::multi::separated_list0(
    nom::character::complete::space0,
    syllable,
)(i)?;

但是,在消耗完所有令牌后,我会收到 Err(Error(Error { input: "", code: SeparatedList }))

【问题讨论】:

    标签: parsing rust nom


    【解决方案1】:

    使用问题

    nom::multi::separated_list0(
        nom::character::complete::space0,
        syllable,
    )(i)?;
    

    space0分隔符匹配空字符串,所以它会到达输入字符串的末尾,separated_list0会继续尝试消耗空字符串,因此Err(Error(Error { input: "", code: SeparatedList }))

    在我的情况下,解决方案是使用 nom::multi::many1 并处理内部解析器中的可选空格,而不是像这样的 nom::multi::separated_list0

    fn syllables(i: &str) -> IResult<&str, Vec<Syllable>> {
        // many ? instead of separated_list0
        multi::many1(syllable)(i)
    }
    
    fn syllable(i: &str) -> IResult<&str, Syllable> {
        let (rest, (_, pronunciation, tone)) = sequence::tuple((
    
            // and handle the optional space
            //              here ?
            character::complete::space0,
            character::complete::alpha1,
            character::complete::digit0,
        ))(i)?;
    
        Ok((rest, Syllable::new(pronunciation, tone)))
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-23
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 2012-04-25
      • 1970-01-01
      • 2011-08-18
      相关资源
      最近更新 更多