ANTLR4 правило лексера, гарантирующее, что выражение не заканчивается символом - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть синтаксис, где мне нужно соответствовать, учитывая следующий пример:

some-Text->more-Text

Из этого примера мне нужны правила лексера ANTLR4, которые бы соответствовали 'some-Text' и 'more-Text' водно правило лексера и «->» как другое правило.

Я использую правила лексера, показанные ниже, в качестве отправной точки, но проблема в том, что символ «-» разрешен в правиле NAMEDELEMENT,что приводит к тому, что первое совпадение NAMEDELEMENT становится 'some-Text-', что приводит к тому, что '->' не фиксируется правилом EDGE.

Я ищу способ убедиться, что '- 'не фиксируется как последний символ в правиле NAMEDELEMENT (или какой-либо другой альтернативе, которая дает желаемый результат).

EDGE
    :   '->'
    ;

NAMEDELEMENT  
    :   ('a'..'z'|'A'..'Z'|'_'|'@') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')* { _input.LA(1) != '-' && _input.LA(2) != '>' }?
    ;

Я пытаюсь использовать вышеуказанный предикат для поиска последовательности' -'и'> ', но это не похоже на работу.Похоже, что он вообще ничего не делает, так как получает одинаковые результаты синтаксического анализа как с предикатом, так и без него.

Правила синтаксического анализа таковы, где я сопоставляю правила «селектора»:

selector
    :   namedelement (edge namedelement)*
    ;

edge
    :   EDGE
    ;

namedelement
    :   NAMEDELEMENT
    ;

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Попробуйте это:

NAMEDELEMENT
 : [a-zA-Z_@] ( '-' {_input.LA(1) != '>'}? | [a-zA-Z0-9_] )*
 ;

Не уверен, что _input.LA(1) != '>' в порядке со средой выполнения JavaScript, но в Java он правильно маркирует "some-->more" в "some-", "->" и "more".

0 голосов
/ 08 февраля 2019

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

(я использую незакомментированную версиютак что я могу поставить точку останова в сгенерированном лексере, чтобы убедиться, что тест на равенство оценивается правильно.)

NAMEDELEMENT  
    //: [a-zA-Z_@] [a-zA-Z_-]* { String.fromCharCode(this._input.LA(1)) != ">" }? 
    : [a-zA-Z_@] [a-zA-Z_-]* { (function(a){
            var c = String.fromCharCode(a._input.LA(1));
            return c != ">";
        })(this)
    }? 
    ;

Мой целевой язык - JavaScript, и отлично подходят как закомментированные, так и некомментированные формы предиката.

...