AST с фиксированными узлами вместо узлов ошибок в antlr - PullRequest
1 голос
/ 14 мая 2010

У меня есть сгенерированный antlr анализатор Java, использующий цель C, и он работает довольно хорошо. Проблема в том, что я также хочу, чтобы он анализировал ошибочный код и создавал значимый AST. Если я передаю ему минимальный Java-класс с одним импортом, после которого точка с запятой отсутствует, он создает два объекта «Tree Error Node», в которых токен import и токены импортируемого класса должны быть.

Но так как он правильно анализирует следующий код и создает правильные узлы для этого кода, он должен восстановиться после ошибки путем добавления точки с запятой или повторной синхронизации. Есть ли способ заставить antlr отражать этот фиксированный ввод, который он вырабатывает внутри AST? Или я могу хотя бы получить токены / текст, которые как-то породили «Ошибки узлов дерева»?

В целях C antlr3commontreeadaptor.c около строки 200 следующий фрагмент указывает, что цель C пока создает только фиктивные узлы ошибок:

static  pANTLR3_BASE_TREE
errorNode                               (pANTLR3_BASE_TREE_ADAPTOR adaptor,   pANTLR3_TOKEN_STREAM ctnstream, pANTLR3_COMMON_TOKEN startToken, pANTLR3_COMMON_TOKEN stopToken, pANTLR3_EXCEPTION e)
{
    // Use the supplied common tree node stream to get another tree from the factory
    // TODO: Look at creating the erronode as in Java, but this is complicated by the
    // need to track and free the memory allocated to it, so for now, we just
    // want something in the tree that isn't a NULL pointer.
    //
    return adaptor->createTypeText(adaptor, ANTLR3_TOKEN_INVALID, (pANTLR3_UINT8)"Tree Error Node");
}

Мне здесь не повезло, и только те узлы ошибок, которые выдает цель Java, позволили бы мне получить текст ошибочных узлов?

Ответы [ 2 ]

0 голосов
/ 14 июня 2010

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

Каждый оператор импорта Java переводится в поддерево AST с искусственным символом IMPORT, например, в качестве корня. Чтобы убедиться, что я могу отличить AST от правильного и ошибочного кода, правила для ошибочных операторов переписывают их в AST с корневым символом с префиксом ERR_, поэтому в примере с оператором импорта корневым символом будет ERR_IMPORT.

Для кодирования более подробной информации об ошибке разбора можно использовать больше различных корневых символов.

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

0 голосов
/ 14 мая 2010

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

...