правило синтаксического анализа строки antlr имеет прецедент над другими правилами - PullRequest
0 голосов
/ 05 июля 2019

У меня есть следующая грамматика:

cell
    : operator value
    ;

operator
    : EQ
    ;

value
    : StringCharacters
    ;

EQ
    : '='
    ;

StringCharacters
    :   StringCharacter+
    ;
fragment
StringCharacter
    :   ~[\\\r\n]
    ;

WS  :  [ \t\r\n\u000C]+ -> skip
    ;

Идея состоит в том, чтобы разрешить следующие входные данные:

= 3
=3
=asdkfljer
=skdfj wkrje slkjf 

и т. Д., И синтаксический анализатор все время распознает предшествующий оператор. Но это точно не то, что происходит. Вместо этого анализатор всегда распознает все как значение.

Как я могу реализовать грамматику таким образом, чтобы синтаксический анализатор всегда сначала распознавал оператор и в основном принимал остальное как значение?

1 Ответ

1 голос
/ 06 июля 2019

Проблема в том, что StringCharacters соответствует любой вашей входной строке, а ANTLR берет токен с максимально возможной длиной.

Для решения этой проблемы я бы предложил использовать Лексические режимы , что-то вроде:

EQ
    : '=' -> pushMode(VALUE_MODE)
    ;

mode VALUE_MODE;

StringCharacters
    :   StringCharacter+ -> popMode
    ;

fragment
StringCharacter
    :   ~[\\\r\n]
    ;

WS  :  [ \t\r\n\u000C]+ -> skip
    ;

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

Если вы хотите проанализировать несколько строк значений, вам нужно изменить лексер и анализатор:

Лексер:

EQ
    : '=' -> pushMode(VALUE_MODE)
    ;

mode VALUE_MODE;

StringCharacters
    :   StringCharacter+ [\r\n]* -> popMode
    ;

fragment
StringCharacter
    :   ~[\\\r\n]
    ;

WS  :  [ \t\r\n\u000C]+ -> skip
    ;

Parser:

cell
    : (operator value)*
    ;

operator
    : EQ
    ;

value
    : StringCharacters
    ;
...