ANTLR4 правила приоритета - PullRequest
0 голосов
/ 30 ноября 2018

Я пытаюсь заставить простую грамматику работать с использованием ANTLR4.В основном это список ключевых слов, разделенных ;, которые можно отменить, используя Not.Примерно так, например:

Not negative keyword;positive

Я написал следующую грамматику:

grammar input;

input               : clauses;
keyword             : NOT? WORD;
clauses             : keyword (SEPARATOR clauses)?;

fragment N          : ('N'|'n') ;
fragment O          : ('O'|'o') ;
fragment T          : ('T'|'t') ;
fragment SPACE      : ' ' ;

SEPARATOR           : ';';
NOT                 : N O T SPACE;
WORD                : ~[;]+;

Моя проблема в том, что в правиле keyword, WORD, кажется, имеет больший приоритетчем NOT.Not something распознается как слово Not something вместо отрицательного something.

Например, дерево разбора, которое я получаю, это

this.

То, что я пытаюсь достичь, это что-то вроде этого

like this

Как вы можете сделать выражение более приоритетным по сравнению с другим в ANTLR4?Любой совет по исправлению этого?

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

Спасибо за ваше время!

1 Ответ

0 голосов
/ 01 декабря 2018

У вас нет явного правила пробелов, и вы включаете пробелы в правило WORD.И все же вы хотите, чтобы слова были разделены пробелами.Это не может работать.Не включайте в слова пробелы (в любом случае это противоречит обычному значению слова).Вместо этого укажите точно, что на самом деле является словом (обычно это комбинация букв и цифр, а не буквы).Кроме того, я бы реструктурировал грамматику так, чтобы positive и negative не были частью keyword, а имели отдельные права.Здесь я определил их как собственные ключевые слова, но если это не то, что вы хотите, замените их просто WORD:

grammar input;

input               : clauses EOF;
keyword             : NOT? (POSITIVE | NEGATIVE) WORD?;
clauses             : keyword (SEPARATOR keyword)*;

fragment A: [aA];
fragment B: [bB];
fragment C: [cC];
fragment D: [dD];
fragment E: [eE];
fragment F: [fF];
fragment G: [gG];
fragment H: [hH];
fragment I: [iI];
fragment J: [jJ];
fragment K: [kK];
fragment L: [lL];
fragment M: [mM];
fragment N: [nN];
fragment O: [oO];
fragment P: [pP];
fragment Q: [qQ];
fragment R: [rR];
fragment S: [sS];
fragment T: [tT];
fragment U: [uU];
fragment V: [vV];
fragment W: [wW];
fragment X: [xX];
fragment Y: [yY];
fragment Z: [zZ];

SEPARATOR : ';';
NOT       : N O T;
POSITIVE  : P O S I T I V E;
NEGATIVE  : N E G A T I V E;

fragment LETTER: DIGIT | LETTER_NO_DIGIT;
fragment LETTER_NO_DIGIT: [a-zA-Z_$\u0080-\uffff];
WORD: LETTER_NO_DIGIT LETTER*;
WHITESPACE: [ \t\f\r\n] -> channel(HIDDEN);
fragment DIGIT:    [0-9];
fragment DIGITS: DIGIT+;

, что дает вам это дерево разбора для ввода:

enter image description here

...