Почему Lexer.cs не распознает лексический режим? - PullRequest
0 голосов
/ 20 января 2020

Я видел много примеров реализации лексических режимов на этом сайте, а также в других местах, таких как Полное руководство по ANTLR4. Прежде чем написать собственную грамматику лексера с лексическими режимами, я просто хотел попробовать пример. Поэтому я скопировал пример из ANTLR Mega Tutorial :

lexer grammar MarkupLexer;
OPEN                : '[' -> pushMode(BBCODE) ;
TEXT                : ~('[')+ ;
// Parsing content inside tags
mode BBCODE;
CLOSE               : ']' -> popMode ;
SLASH               : '/' ;
EQUALS              : '=' ;
STRING              : '"' .*? '"' ;
ID                  : LETTERS+ ;
WS                  : [ \t\r\n] -> skip ;
fragment LETTERS    : [a-zA-Z] ;

и импортировал его в очень простую грамматику синтаксического анализатора:

grammar Example1;
import MarkupLexer;

any                 : .*;

Все, что я хотел увидеть было бы, если бы оно было успешно построено. Однако я столкнулся с той же ошибкой: The name 'BBCODE' does not exist in the current context с ошибкой, возникающей в этом автоматически сгенерированном методе:

private void OPEN_action(RuleContext _localctz, int actionIndex) {
    switch (actionIndex) {
    case 0: PushMode(BBCODE); break;
    }
}

Я заметил, что массив modeNames в автоматически сгенерированном Lexer содержит только "DEFAULT_MODE".

Что мне здесь не хватает? Почему это не строить?

1 Ответ

2 голосов
/ 20 января 2020

Проблема в том, что вы используете «импорт», когда вместо него следует использовать «options {tokenVocab = MarkupLexer;}». Ваши грамматики должны быть:

MarkupParser.g4:

parser grammar MarkupParser;

options {
    tokenVocab = MarkupLexer ;
}

any                 : .*;

MarkupLexer.g4:

lexer grammar MarkupLexer;
OPEN                : '[' -> pushMode(BBCODE) ;
TEXT                : ~('[')+ ;
// Parsing content inside tags
mode BBCODE;
CLOSE               : ']' -> popMode ;
SLASH               : '/' ;
EQUALS              : '=' ;
STRING              : '"' .*? '"' ;
ID                  : LETTERS+ ;
WS                  : [ \t\r\n] -> skip ;
fragment LETTERS    : [a-zA-Z] ;
...