Что такое древовидный синтаксический анализатор в ANTLR, и я вынужден записать тот?

У меня все еще есть проблемы с алиасами в моем коде (из-за initb) или это безопасно делать?

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

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

Используйте memcpy вместо:

void inita(ctx_t *ctx, uint8_t *aptr)
{
    memcpy(ctx->a, aptr, sizeof uint64_t);
}
6
задан HipsterZipster 30 March 2009 в 15:41
поделиться

3 ответа

Я нашел этот ответ на вопрос на jGuru записанным Terence Parr, который создал ANTLR. Я скопировал это объяснение с сайта, связанного здесь:

Только простые, так называемые синтаксически ориентируемые переводы могут быть сделаны с действиями в рамках синтаксического анализатора. Эти виды переводов могут только выложить конструкции, которые являются функциями информации, уже замеченной в той точке в синтаксическом анализе. Древовидные синтаксические анализаторы позволяют Вам обходить промежуточную форму и управлять тем деревом, постепенно превращая его по нескольким фазам перевода к конечной форме, которая может быть легко распечатана назад как новый перевод.

Вообразите простую проблему перевода, где Вы хотите распечатать страницу HTML, заголовок которой "Существуют n объекты", где n является количеством идентификаторов, Вы нашли во входном потоке. Идентификаторы должны быть распечатаны после заголовка как это:

<html>
<head>
<title>There are 3 items</title>
</head>
<body>
<ol>
<li>Dog</li>
<li>Cat</li>
<li>Velociraptor</li>
</body>
</html>

от входа

Dog
Cat
Velociraptor

Таким образом с простыми действиями в Вашей грамматике, как можно вычислить заголовок? Вы не можете, не читая целый вход. Хорошо, поэтому теперь мы знаем, что нам нужна промежуточная форма. Лучшим обычно является AST, который я нашел, так как он записывает входную структуру. В этом случае это - просто список, но это демонстрирует мою точку.

Хорошо, теперь Вы знаете, что дерево является хорошей вещью для чего-либо кроме простых переводов. Учитывая AST, как Вы становитесь произведенными от него? Вообразите деревья простого выражения. Один путь состоит в том, чтобы сделать узлы в древовидных определенных классах как PlusNode, IntegerNode и так далее. Затем Вы просто просите, чтобы каждый узел распечатал себя. Для входа 3+4 у Вас было бы дерево:

+ | 3 - 4

и классы

class PlusNode extends CommonAST {
  public String toString() {
    AST left = getFirstChild();
    AST right = left.getNextSibling();
    return left + " + " + right;
  }
}

class IntNode extends CommonAST {
  public String toString() {
    return getText();
  }
}

Учитывая дерево выражений, можно перевести его назад для отправки текстовых сообщений с t.toString (). Так, что случилось с этим? Кажется, работает отлично, исправляется? Это, кажется, работает хорошо в этом случае, потому что это просто, но я утверждаю, что, даже для этого простого примера, древовидные грамматики более читаемы и являются формализованными описаниями точно, что Вы кодировали в PlusNode.toString ().

expr returns [String r]
{
    String left=null, right=null;
}

: #("+" left=expr right=expr) {r=left + " + " + right;}
| i:INT                       {r=i.getText();}
;

Обратите внимание, что определенный класс ("неоднородный AST") подход на самом деле кодирует полный синтаксический анализатор с рекурсивным спуском для # (+ INT INT) вручную в toString (). Как люди парсера-генератора, это должно заставить Вас съежиться.;)

Основная слабость неоднородного подхода AST - то, что он не может удобно получить доступ к контекстной информации. В синтаксическом анализаторе с рекурсивным спуском легко получают доступ к Вашему контексту, потому что он может быть передан в в качестве параметра. Вы также знаете точно, который может вызвать правило, который другое правило (например, является это выражение НЕКОТОРОЕ ВРЕМЯ условием или ЕСЛИ условие?) путем рассмотрения грамматики. Класс PlusNode выше существует в отдельном, изолированном мире, где он понятия не имеет, кто вызовет, это - toString () метод. Хуже, программист не может сказать, в котором контексте это будет вызвано путем чтения его.

Таким образом, добавление действий к Вашему входному синтаксическому анализатору работает на очень простые переводы где:

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

Вне этого Вам будет нужна промежуточная форма - AST обычно является лучшей формой. Используя грамматику для описания структуры AST походит на использование грамматики для парсинга входного текста. Формализованные описания на проблемно-ориентированном высокоуровневом языке как ANTLR лучше, чем рука кодировала синтаксические анализаторы. Действия в древовидной грамматике имеют очень ясный контекст и могут удобно получить доступ к информации, переданной от вызова правил. Переводы, которые управляют деревом для многопроходных переводов, являются также намного более легким использованием древовидной грамматики.

3
ответ дан 9 December 2019 в 22:39
поделиться

Создание AST с ANTLR включено в грамматику. Вы не должны делать этого, но это - действительно хороший инструмент для более сложных требований. Это - учебное руководство на древовидной конструкции, которую можно использовать.

В основном, с ANTLR, когда источник становится проанализированным, у Вас есть несколько опций. Можно сгенерировать код, или использование AST переписывают правила в грамматике. AST в основном в представлении памяти Вашего источника. Оттуда, существует много, можно сделать.

Существует много к ANTLR. Если бы Вы уже не имеете, я рекомендовал бы получить книгу.

7
ответ дан 9 December 2019 в 22:39
поделиться

Я думаю, что создание AST является дополнительным. Абстрактное синтаксическое дерево полезно для последующей обработки как семантический анализ проанализированной программы.

Только можно решить, необходимо ли создать тот. Если Ваша единственная цель является синтаксической проверкой затем, Вы не должны генерировать тот. В javacc (подобный ANTLR) существует утилита под названием JJTree, который позволяет поколение AST. Таким образом, я предполагаю, что это является дополнительным в ANTLR также.

1
ответ дан 9 December 2019 в 22:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: