Подстановочный оператор ANTLR не использует ожидаемый ввод - PullRequest
1 голос
/ 13 марта 2019

Я пишу грамматику antlr, которая читается в файле спецификации yacc. Спецификации Yacc имеют вид

declarations 
%%
rules 
%%
programs 

Однако меня интересуют только разделы объявлений и правил в файле спецификаций yacc. Я определил правила, которые хорошо соответствуют объявлениям и правилам, но я пытался сопоставить все, что идет после второго «%%», используя оператор подстановки (. *?). Это не удается. Вот
Ссылка на мою грамматику anltr для грамматик yacc

Как мне сопоставить все, что идет после второго «%%».

Я также пытался сопоставить что угодно, кроме EOF, используя

<some_rule> : ~(EOF)* ;

Вот пример файла, который терпит неудачу

1 Ответ

2 голосов
/ 14 марта 2019

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

Таким образом, вы начинаете в режиме объявления по умолчанию, и когда вы впервые сталкиваетесь с %%, вы нажимаете на RULE_MODE. Когда вы сталкиваетесь с другим %%, вы нажимаете на SUBROUTINE_MODE. В этом последнем режиме вы просто skip видите всех персонажей.

Небольшая демонстрация:

// File: YaccLexer.g4
lexer grammar YaccLexer;

DECLARATION_TOKEN
 : [a-zA-Z]+
 ;

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

DECLARATION_END
 : '%%' -> skip, pushMode(RULE_MODE)
 ;

mode RULE_MODE;

  RULE_TOKEN
   : [a-zA-Z]+
   ;

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

  RULE_END
   : '%%' -> skip, pushMode(SUBROUTINE_MODE)
   ;

mode SUBROUTINE_MODE;

  ANY
   : . -> skip
   ;

Если вы генерируете лексер из приведенной выше грамматики и токенизируете ввод:

foo
bar

%%

baz

%%

ignore
me

будут созданы следующие токены:

DECLARATION_TOKEN         'foo'
DECLARATION_TOKEN         'bar'
RULE_TOKEN                'baz'

Вы можете использовать YaccLexer в грамматике вашего синтаксического анализатора следующим образом:

// File: YaccParser.g4
parser grammar YaccParser;

options {
  tokenVocab= YaccLexer;
}

// your parser rules here
...