Как заставить ANTLR выводить иерархические AST? - PullRequest
3 голосов
/ 23 декабря 2009

У меня есть Lua грамматика , (незначительные изменения, чтобы получить его для вывода на C #, только директивы пространства имен и несколько изменений опций), и когда я запускаю его на некотором примере ввода, он возвращает мнедерево с корневым узлом «ноль» и потомками, что выглядит как токенизированная версия входного кода.Похоже, грамматики дерева ANTLR работают на иерархических деревьях, а не на "плоских", поэтому я не думаю, что могу использовать вывод как есть.

Есть ли простойисправить грамматику или ее нужно переписать с нуля?

1 Ответ

6 голосов
/ 23 декабря 2009

Предполагая, что ваше дерево - это просто одномерный список узлов, вот как вы можете создать иерархию родителей / братьев и сестер:

В ANTLR есть два оператора для создания AST:

!     excludes the node (token) from the (sub)tree;
^     makes a node the root of a (sub)tree.

Когда оператор не предоставлен, узлы / токены добавляются как дочерние элементы текущего корня. Вероятно, именно это и произошло с вами: все, что вы видите, это одномерный список узлов / токенов.

Пример:

grammar Exp;

options {output=AST;}

// ... some rules ...

addition
  :  Integer '+'^ Integer ';'!
  ;

Integer
  :  '0'
  |  '1'..'9' '0'..'9'*
  ;

Правило addition создаст следующее дерево для выражения 6+9;:

   +
  / \
 /   \
6     9

Как видите: + - это корень (после него ^), числа являются токенами (у них нет оператора), и точка с запятой исключается (после нее стоит !). ).

Подробное объяснение см. В главе 7 «Построение дерева» из Полное руководство по ANTLR . Я настоятельно рекомендую вам получить копию.

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

Удачи!

...