0

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

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

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

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

Err(Error(Error { input: "", code: SeparatedList }))但是,在所有代币都被消耗后,我得到了一个。

4

1 回答 1

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)))
}
于 2021-04-23T20:31:47.063 回答