Правило лексера Antlr4 должно совпадать только в начале строки - PullRequest
1 голос
/ 24 февраля 2020

Я использую Antlr4 с JavaScript и C#. У меня есть правило, которое должно соответствовать, только если оно находится в начале строки. Если выражение начинается с REM , оно должно быть распознано как комментарий и, следовательно, скрыто. В противном случае это не комментарий.

  • REM 1 + 1 является комментарием
  • 1 + 1 REM 2 не является комментарием

Ниже код в моем Lexer является лучшим I мог сделать до сих пор. Но проблема в том, что это работает, только если есть новая строка, перед которой на самом деле это не так хорошо.

START_COMMENT   : ('\r\n' | '\n' | '\f') ([R][E][M] | [;] | [@][ ]) ~[\r\n]* -> channel(HIDDEN);

Мне интересно знать, есть ли какая-то хитрость, чтобы сказать Лексеру, что правило должно совпадать, только если оно находится в начале строки и больше нигде?

Ответы [ 2 ]

2 голосов
/ 24 февраля 2020

Вы можете использовать предикат , который проверяет, равен ли текущий индекс символа лексера 0 (указывая начало строки). Недостатком этого является то, что вы добавляете целевой код c в вашу грамматику. Для JavaScript это должно работать:

REMARK
 : {this.getCharIndex() === 0}? ( R E M | ';' | '@ ' ) ~[\r\n]*
 ;

framgment R : [rR];
framgment E : [eE];
framgment M : [mM];
1 голос
/ 25 февраля 2020

это, вероятно, хакерский способ сделать это, но когда у меня возникла эта проблема, я просто сказал ей искать новую строку перед ней, а затем в своем коде я проверил, должна ли введенная строка начинаться с это, и в этом случае я добавил новую строку в верхней части. Так что я в основном сделал это

comment: NEWLINE '//';
NEWLINE: [\r\n] -> skip;

, затем в моем коде:

if (content.startsWith("//")) {
    content = "\n" + content;
}

Конечно, это имеет тот недостаток, что любые ошибки заключаются в одной строке, но это может работать в вашем случае.

...