Как предотвратить сообщение ключевых слов слушателю, когда Antlr все равно правильно их анализирует?(вид пропускает их) - PullRequest
0 голосов
/ 26 декабря 2018

[ANTLR 4.7.1]
Я хочу, чтобы мой анализатор не передавал ключевые слова моему слушателю, поскольку, когда я нахожусь в обратном вызове правила ввода foo_statement, я уже знаю, какое ключевое словоесть и не нужен как токен.
Поэтому я пытаюсь отправить его на канал HIDDEN, но не работает:

grammar foo;
program: foo_statement EOF;
foo_statement: FOO_KEYWORD NUMBER;
FOO_KEYWORD: 'foo' -> channel(HIDDEN);
NUMBER: [0-9]+;
WS: [ \t\r\n] -> skip;  

grun foo program -tokens -tree
foo 1
[@0,0:2='foo',<'foo'>,channel=1,1:0]
[@1,4:4='1',<NUMBER>,1:4]
[@2,5:4='<EOF>',<EOF>,1:5]
line 1:4 missing 'foo' at '1'
(program (foo_statement <missing 'foo'> 1) <EOF>)

Поэтому я пытаюсь создать специальный канал дляключевые слова:

grammar foo;
@lexer::members {
    public static final int KEYWORDS = 2;
}
/*...*/
FOO_KEYWORD: 'foo' -> channel(KEYWORDS);
/*...*/

но я получаю это: (я думаю, что синтаксис не работает с 4.6)

error(177): KEYWORDS is not a recognized channel name

Я пробую новое определение каналов:

grammar foo;
channels { KEYWORDS }
/*...*/
FOO_KEYWORD: 'foo' -> channel(KEYWORDS);
/*...*/

Но я получаю:

error(164): custom channels are not supported in combined grammars

Затем я разделяю синтаксический анализатор и лексер:

/* foo.g4 */
grammar foo;
import fooLexer;
program: foo_statement EOF;
foo_statement: FOO_KEYWORD NUMBER;

/* fooLexer.g4 */
lexer grammar fooLexer;
channels { KEYWORDS }
FOO_KEYWORD: 'foo' -> channel(KEYWORDS);
/*...*/

Но я получаю:

error(164): custom channels are not supported in combined grammars
error(113): combined grammar foo and imported lexer grammar fooLexer 

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

parser grammar foo;
import fooLexer;

error(163): custom channels are not supported in parser grammars
error(111): parser grammar foo cannot import lexer grammar fooLexer
error(52): lexer rule FOO_KEYWORD not allowed in parser  

Тогда antlr жалуется на то, чтограмматика синтаксического анализатора foo не может иметь правил лексера, поэтому при импорте другой грамматики это выглядит так же, как в стиле C #include.

Итак, как я могу использовать каналы в Antlr 4.7.1?
Или как мне достичь своей цели - запретить анализатору сообщать о ключевых словах, но по-прежнему правильно их анализировать?

...