gpt4 book ai didi

parsing - 使用 nom 解析多行注释

转载 作者:行者123 更新时间:2023-11-29 08:30:46 43 4
gpt4 key购买 nike

我正在尝试编写一个识别多行注释的 nom 解析器...

/*
yo!
*/

...并消耗/丢弃(同样的事情,对吧?)结果:

use nom::{
bytes::complete::{tag, take_until},
error::{ErrorKind, ParseError},
sequence::preceded,
IResult,
};

fn multiline_comment<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
preceded(tag("/*"), take_until("*/"))(i)
}

这几乎行得通。我知道 take_until 在 */ 之前停止,但我不知道如何让它包含它。

#[test]
fn should_consume_multiline_comments() {
assert_eq!(
multiline_comment::<(&str, ErrorKind)>("/*abc\n\ndef*/"),
Ok(("", "/*abc\n\ndef*/"))
);
}

给出结果

thread 'should_consume_multiline_comments' panicked at 'assertion failed: `(left == right)`
left: `Ok(("*/", "abc\n\ndef"))`,
right: `Ok(("", "/*abc\n\ndef*/"))`'

所以我的问题是,如何获得完整的评论,包括结尾 */

谢谢!

最佳答案

我假设您真的不希望返回的字符串在 /* 和结束 */ 之前完好无损 - 因为 总是丢弃来自第一个解析器的匹配项,你永远不会使用 preceded 获得它。我假设您主要关心的是确保结束 */ 实际被消耗。

为此,您可以使用 delimited 而不是 preceded:

fn multiline_comment<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
delimited(tag("/*"), is_not("*/"), tag("*/"))(i)
}

这通过了这个测试:

assert_eq!(
multiline_comment1::<(&str, ErrorKind)>("/*abc\n\ndef*/"),
Ok(("", "abc\n\ndef"))
);

所以你可以确定关闭的*/已经被消费了。

关于parsing - 使用 nom 解析多行注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58572819/

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com