есть ли способ обработать все типы исключений antlr в блоке catch [...] правила - PullRequest
1 голос
/ 22 апреля 2011

Я использую ANTLR3 со средой выполнения C.

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

По этому правилу я запишу его в журнал, а затем попытаюсь возобновить.

Я установил метод перехвата правил так, чтобы все правила не пытались восстановить.

@rulecatch 
{
    if (HASEXCEPTION())
    {
    PREPORTERROR();
    }
}

Это позволяет мне добавлять обработчики перехвата в нужные мне правила.

В соответствии с моим правилом я могу использовать синтаксис перехвата следующим образом:

catch [ANTLR3_RECOGNITION_EXCEPTION]
{
    PREPORTERROR();
    RECOGNIZER->consumeUntil(RECOGNIZER,RCURLY);
    CONSUME();
    PSRSTATE->error = ANTLR3_FALSE;
    PSRSTATE->failed = ANTLR3_FALSE;
     }

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

Есть ли способ сделать это?

Я думал, что мог бы перегрузить все функции восстановления, но затем какой-то код генерирует исключения, например, так:

                    CONSTRUCTEX();
                    EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
                    EXCEPTION->message      = (void *)"";
                    EXCEPTION->decisionNum  = 23;
                    EXCEPTION->state        = 0;


                    goto rulewhenEx;

, что означает, что мне нужно поймать все возможные исключения.

Есть мысли ??

1 Ответ

2 голосов
/ 20 мая 2011

В итоге я попробовал два решения для этого.

Подход 1)

Перегрузка параметра rulecatch для установки типа исключения для одного определенного типа

@rulecatch 
{
    if (HASEXCEPTION())
    {

    // This is ugly.  We set the exception type to ANTLR3_RECOGNITION_EXCEPTION so we can always
    // catch them.
    PREPORTERROR();
    EXCEPTION->type = ANTLR3_RECOGNITION_EXCEPTION;
    }
}

Это позволяет мне использовать один блок catch, поскольку все исключения будут этого типа.

Подход 2)

Я просто использую несколько блоков перехвата, и все они отправляют в общую функцию для обработки ошибки

catch [ANTLR3_RECOGNITION_EXCEPTION]
{
    handleException();
}
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
    handleException();
}
....
...