2012-06-26 2 views
3

Я пытаюсь создать правило, которое будет переписываться во вложенное дерево (похожее на двоичное дерево).Правило ANTLR переписывает вложенное дерево

Например:

a + b + c + d; 

бы разобрать на дерево, как (((a + b) + c) + d). В основном каждый корневой узел будет иметь трех детей (LHS '+' RHS), где LHS может быть более вложенными узлами.

Я пытался кое-как:

rule: lhs '+' ID; 
lhs: ID | rule; 

и

rule 
    : rule '+' ID 
    | ID '+' ID; 

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

EDIT: Моя последняя попытка рекурсивно на правой стороне, которая дает обратное тому, что я хочу:

rule:
ID (op='+' rule)?
-> {op == null}? ID
-> ^(BinaryExpression<node=MyBinaryExpression> ID $op rule)

Придает (a + (b + (c + d)))

+0

Вы должны использовать вложенные выражения, поскольку ANTLR является LL (*). См. [Этот вопрос] (http://stackoverflow.com/questions/1452729/antlr-grammar-for-expressions?rq=1). Или вы можете сделать это в парсере дерева, что может быть проще и быстрее в зависимости от вашей грамматики. –

+0

Если 'a + b' - все дочерние узлы, то какой корень? Почему вы не хотите, чтобы оператор был root? –

+0

Корневой узел является мнимым узлом. Древовидная структура является частью требований, над которыми я работаю. –

ответ

2

Последующий Грамматика:

grammar T; 

options { 
    output=AST; 
} 

tokens { 
    BinaryExpression; 
} 

parse 
: expr ';' EOF -> expr 
; 

expr 
: (atom -> atom) (ADD a=atom -> ^(BinaryExpression $expr ADD $a))* 
; 

atom 
: ID 
| NUM 
| '(' expr ')' 
; 

ADD : '+'; 
NUM : '0'..'9'+; 
ID : 'a'..'z'+; 
SPACE : (' ' | '\t' | '\r' | '\n')+ {skip();}; 

разбирает ввод "a + b + c + d;" следующим образом:

enter image description here

+0

Это прекрасно, спасибо Барту. –

+0

Добро пожаловать @NicWolfe. –

0

ли вы попробовать

rule: ID '+' rule | ID; 

?

+0

Да, это дает мне дерево, обратное к тому, что я хочу: '(a + (b + (c + d)))' –

Смежные вопросы