Antlr одно дочернее дерево с использованием правил перезаписи - PullRequest
1 голос
/ 20 июля 2011

У меня есть эта формула:

negationExpr : ОТРИЦАНИЕ ^ * атом ;

атом
: 'a' .. 'z' | 'A' .. 'Z';

С вышеприведенными правилами грамматики, если я введу формулу, я получу такую ​​древовидную структуру:

¬ являющийся корневым узлом, ¬ оставленный ребенок; правильное дитя

Однако, что я хотел бы иметь: ¬ будучи корневым узлом, второй ¬ является единственным потомком указанного узла существо, единственное дитя второго ¬

В принципе, я наблюдал, как все знаки ОТРИЦАНИЯ имеют только одного ребенка, это возможно? Я знаю, что мы можем использовать «правило перезаписи» для реструктуризации дерева, но я не знаю, как это сделать.

Любая помощь или советы приветствуются! Спасибо!

Ответы [ 2 ]

1 голос
/ 20 июля 2011

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

rule :
   alt1 -> rewriteRule1
 | alt2 -> rewriteRule2
 ...
 | altN -> rewriteRuleN;

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

negationExpr :
   NEGATION negationExpr 
     -> ^(NEGATION negationExpr)
 | atom 
     -> atom;

Это добавит уровень в дереве для каждого оператора отрицания. ^ Создаст корень для токена сразу после скобок и добавит результат следующего правила negationExpr в качестве дочернего.

0 голосов
/ 20 июля 2011

Предложение Adam12 - элегантное решение. У меня есть только одно замечание о вашем (JiandongC) фрагменте кода и еще один возможный способ построения AST.

Обратите внимание, что .. (оператор диапазона) недопустим в правилах синтаксического анализа! Вам нужно сделать Atom правилом лексера или выполнить:

atom 
  :  LETTER
  ; 

LETTER 
  :  'a'..'z' | 'A'..'Z'
  ;

Что касается создания AST, вы могли бы также позволить просто игнорировать четное число NEGATION токенов, поскольку - - будет положительным.

negationExpr 
  :  (NEGATION NEGATION)* ( NEGATION atom -> ^(NEGATION atom)
                          | atom          -> atom
                          )
  ;

вышеприведенное правило просто создает ^(NEGATION atom), если имеется неравное число NEGATION токенов, иначе atom будет создан как один узел (корень).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...