Что является эквивалентом времени выполнения Antlr3 C для создания исключения для отчетов об ошибках - PullRequest
2 голосов
/ 20 января 2011

Я довольно хорошо знаком с Antlr 2.X и целями Anthr 3.1.X CSharp и python.

Однако теперь я вынужден использовать цель проекта Antlr 3 C.

Моя проблема в том, как сообщить об ошибках в моей грамматике или древовидной грамматике.

Рассмотрим правило, соответствующее токену, и мы поместим его в карту. Мы хотим, чтобы токен был уникальным. Обычно я выбрасываю исключение, если токен уже есть на карте, и ловлю исключение вне анализатора hte, чтобы сообщить об ошибке.

Что представляет собой среда выполнения Antlr C для следующего правила?

token_match: ID 
{
    if(mp.find($ID.Text))
        throw std::exception("Non unique token found");
}

1 Ответ

2 голосов
/ 21 февраля 2011

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

Сначала вы должны создать свой собственный обработчик ошибок, если вы хотите создать пользовательские типы исключений.Посмотрите на оригинал antlr3baserecognizer.c: 1000.

static void         
displayRecognitionErrorNew  (pANTLR3_BASE_RECOGNIZER recognizer,
                             pANTLR3_UINT8 * tokenNames)
{
...
    switch  (ex->type)
    {
    case    ANTLR3_UNWANTED_TOKEN_EXCEPTION:
...
    case    NUTF_EXCEPTION:
      printf("Non unique token found");
      break;

Затем закодируйте некоторую функцию или код правила для обработки структуры исключений.Посмотрите на antlr3baserecognizer.c: 325, чтобы настроить свое исключение.

ex = antlr3ExceptionNew(ANTLR3_RECOGNITION_EXCEPTION,
                       (void *)ANTLR3_RECOGNITION_EX_NAME,
                       NULL,
                       ANTLR3_FALSE);

ex->type                = NUTF_EXCEPTION
ex->line                = ins->getLine (ins);
ex->charPositionInLine  = ins->getCharPositionInLine    (ins);  
ex->index               = is->index (is);
ex->streamName          = ins->fileName;
ex->message             = "That was totally unexpected";

Далее вам нужно фактически выбросить ваше исключение при обнаружении ошибки.Я думаю, что единственный способ сделать это - переопределить mismatch (), добавив в ваш код и вызвав его из вашего правила.

static  void
mismatchNew(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)
{
  ...
}

Наконец, скажите ANTLR использовать ваши новые функции.

...