Вопрос

Я пишу грамматику Antrl для перевода одного языка в другое, но документация по использованию скрытого канала очень скудна. Я не могу найти пример в любом месте. Единственное, что я нашел, - это FAQ на www.antlr.org, который говорит вам, как получить доступ к скрытому каналу, но не как наилучшим образом использовать эту функциональность. Целевой язык - Java.

В моем грамматике я прохожу пробел и комментарии, как так:

// Send runs of space and tab characters to the hidden channel.        
WHITESPACE 
    :   (SPACE | TAB)+ { $channel = HIDDEN; }
    ;

// Single-line comments begin with --
SINGLE_COMMENT 
    :    ('--' COMMENT_CHARS NEWLINE) {
            $channel=HIDDEN;
        }
    ;

fragment COMMENT_CHARS 
    :   ~('\r' | '\n')*
    ;

// Treat runs of newline characters as a single NEWLINE token.
NEWLINE 
    :   ('\r'? '\n')+ { $channel = HIDDEN; }
    ;

В раздел «Мои члены» я определил метод написания скрытых каналов токенов на мой выходной StringStream ...

@members {

private int savedIndex = 0;

void ProcessHiddenChannel(TokenStream input) {      
    List<Token> tokens = ((CommonTokenStream)input).getTokens(savedIndex, input.index());
    for(Token token: tokens) {
        if(token.getChannel() == token.HIDDEN_CHANNEL) {
            output.append(token.getText());

        }
    }
    savedIndex = input.index();
}
}

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

myParserRule
        :       MYTOKEN1 { ProcessHiddenChannel(input); }
                MYTOKEN2 { ProcessHiddenChannel(input); }
        ;

Конечно, должен быть лучший способ?

Редактировать: Это пример языка ввода:

-- -----------------------------------------------------------------
--
--
--  Name                Description
--  ==================================
--  IFM1/183         Freq Spectrum Inversion
--                     
-- -----------------------------------------------------------------

PROCEDURE IFM1/183

TITLE "Freq Spectrum Inversion";

HELP
      Freq Spectrum Inversion

ENDHELP;

PRIVILEGE CTRL;

WINDOW MANDATORY;

INPUT

   $Input : @NO_YES
   DEFAULT select %YES when /IFMS1/183.VALUE = %NO;
                  %NO otherwise
           endselect
   PROMPT "Spec Inv";

   $Forced_Cmd : BOOLEAN
   Default FALSE
   Prompt  "Forced Commanding";

DEFINE
   &RetCode   : @PSTATUS := %OK;
   &msg       : STRING;
   &Input     : BOOLEAN;

REQUIRE AVAILABLE(/IFMS1)
        MSG "IFMS1 not available";

REQUIRE /IFMS1/001.VALUE = %MON_AND_CTRL
        MSG "IFMS1 not in control mode";

BEGIN  -- Procedure Body --

    &msg := "IFMS1/183 -> " + toString($Input) + " : "; 

-- pre-check

   IF /IFMS1/183.VALUE = $Input
      AND $Forced_Cmd = FALSE THEN
      EXIT (%OK, MSG &msg + "already set");
   ENDIF;

-- command

   IF $Input =  %YES THEN &Input:= TRUE;
    ELSE  &Input:= FALSE;
   ENDIF;

   SET &RetCode := SEND IFMS1.FREQPLAN
        ( $FreqSpecInv := &Input);
   IF &RetCode <> %OK THEN
      EXIT (&RetCode, MSG &msg + "command failed");
   ENDIF;

-- verify

   SET &RetCode := VERIFY /IFMS1/183.VALUE = $Input TIMEOUT '10';
   IF &RetCode <> %OK THEN
      EXIT (&RetCode, MSG &msg + "verification failed");
   ELSE
      EXIT (&RetCode, MSG &msg + "verified");
   ENDIF;

END
Это было полезно?

Решение

Посмотрите на наследование CommontedStream и кормление экземпляра вашего подкласса в ANTLR. Из примера кода, который вы даете, я подозреваю, что вам может быть заинтересован в том, чтобы посмотреть на фильтр и параметры перезаписи, доступные в версии 3.

Кроме того, посмотрите на это другое Связанный вопрос переполнения стека.

Другие советы

Я только что проходил через некоторые из моих старых вопросов и думал, что стоит ответить на окончательное решение, которое работало лучшее. В конце концов, лучший способ перевести язык должен был использовать StringTemplate. Это заботится о перезагрузке на вывод для вас. Существует очень хороший пример под названием «CMINUS» в примерной упаковке ANTLR, который показывает, как его использовать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top