使用 nom 解析多行注释
Parse multiline comment with nom
我正在尝试编写一个识别多行注释的 nom 解析器...
/*
yo!
*/
...和 consumes/discards(同样的事情,对吧?)结果:
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
总是丢弃来自第一个解析器的匹配项,您永远不会使用 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"))
);
所以你可以确定关闭的 */
已经被消耗了。
我正在尝试编写一个识别多行注释的 nom 解析器...
/*
yo!
*/
...和 consumes/discards(同样的事情,对吧?)结果:
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
总是丢弃来自第一个解析器的匹配项,您永远不会使用 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"))
);
所以你可以确定关闭的 */
已经被消耗了。