Разбор многострочного комментария с номом - PullRequest
0 голосов
/ 26 октября 2019

Я пытаюсь написать синтаксический анализатор имени, который распознает многострочные комментарии ...

/*
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*/"))`'

Так что мойВопрос в том, как мне получить полный комментарий, включая окончание */

Спасибо!

1 Ответ

0 голосов
/ 28 октября 2019

Я предполагаю, что вы на самом деле не хотите, чтобы возвращаемая строка имела как предшествующее /*, так и закрывающее */ целое - поскольку 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"))
);

, так что вы можете быть уверены, что закрытие */ было использовано.

...