Пропуск комментария к датам "#;" при создании парсера для R6RS с ANTLR4

Я пытаюсь написать лексер / парсер для R6RS, и я застрял с комментарием, пропускающим данные

Вот некоторая часть моих правил лексера / парсера:

BOOLEAN: '#t' | '#f' | '#T' | '#F';
NUMBER: DIGIT+; // TODO: incomplete
CHAR: '#\\' CHARNAME | '#\\x' HEXDIGIT+ | '#\\' . ;
STRING: '"' STRELEMENT* '"';
IDENTIFIER: INITIAL SUBSEQUENT* | PERCULIAR_ID;

COMMENT: (';' .*? LINE_ENDING | '#!r6rs' ) -> skip;
NESTED_COMMENT: '#|' (NESTED_COMMENT | ~[#|] | ('|' ~'#') | ('#' ~'|') )* '|#' -> skip;

datum: lexemeDatum
     | compoundDatum;
compoundDatum: list
             | vector
             | bytevector;

// (rest omitted...)

Теперь я хочу написать как skipDatum: '#;' datum -> skip, К сожалению, правило парсера не позволяет ->skip, ни SKIPDATUM: '#;' datum -> skip будет работать, потому что правило лексера не может ссылаться на правило парсера.

По моему мнению, в то время как "комментирование" является обязанностью лексера, а "построение данных" является обязанностью парсера, правило относительно #; нужны оба.

Вот мое текущее решение:

skipDatum: '#;' datum;

list: '(' (datum|skipDatum)* ')' #ProperListDatum
    | '[' (datum|skipDatum)* ']' #ProperListDatum
    | '(' skipDatum* datum (datum|skipDatum)* '.' skipDatum* datum skipDatum* ')' #ImproperListDatum
    | '[' skipDatum* datum (datum|skipDatum)* '.' skipDatum* datum skipDatum* ']' #ImproperListDatum

Пока он работает, он кажется таким уродливым; где я действительно хочу написать правила, используя datumЯ всегда должен писать как skipDatum* datum skipDatum*

Есть ли лучшее решение? Заранее спасибо.

1 ответ

Решение

Вы могли бы использовать что-то вроде этого.

datum
    :   SKIP_DATUM? ...
    ;

SKIP_DATUM : '#;';

Это потребует от вас выполнять следующую проверку каждый раз, когда вы используете DatumContext в сгенерированном коде, упрощая грамматику.

if (ctx.SKIP_DATUM() != null) {
    // handle skipped datum here (return?)
}
Другие вопросы по тегам