2013-10-12 5 views
0

В ANTLR: Is there a simple example?, вопрос о antlr3, принятом ответе имеет эту грамматику:Добавить пользовательские атрибуты правил

grammar Exp; 

eval returns [double value] 
    : exp=additionExp {$value = $exp.value;} 
    ; 

additionExp returns [double value] 
    : m1=multiplyExp  {$value = $m1.value;} 
     ('+' m2=multiplyExp {$value += $m2.value;} 
     | '-' m2=multiplyExp {$value -= $m2.value;} 
     )* 
    ; 

multiplyExp returns [double value] 
    : a1=atomExp  {$value = $a1.value;} 
     ('*' a2=atomExp {$value *= $a2.value;} 
     | '/' a2=atomExp {$value /= $a2.value;} 
     )* 
    ; 

atomExp returns [double value] 
    : n=Number    {$value = Double.parseDouble($n.text);} 
    | '(' exp=additionExp ')' {$value = $exp.value;} 
    ; 

Number 
    : ('0'..'9')+ ('.' ('0'..'9')+)? 
    ; 

WS 
    : (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;} 

Он использует атрибут $value для передачи информации на дереве разбора.

Я хочу сделать то же самое antlr4. Похоже, что атрибута $value больше нет. Как добавить пользовательские атрибуты в правила для передачи информации в дерево разбора? Если это не правильный механизм для достижения того, что я хочу, какие механизмы существуют для достижения чего-то подобного?


Я попытался с помощью местных жителей, как это:

/* Store each row in an ArrayList */ 
row 
    locals [ 
    ArrayList<String> cells = null 
    ] 
    : partial_row RowSeparator 
    { 
    $cells = $partial_row.cells; 
    } 
    ; 

partial_row 
    locals [ 
    ArrayList<String> cells = null 
    ] 
    : Cell 
    { 
    $cells = new java.util.ArrayList<String>(); 
    $cells.add($Cell.text); 
    } 
    | partial_row Cell 
    { 
    $cells = $partial_row.cells; 
    $cells.add($Cell.text); 
    } 
    ; 

Но это не работает, что дает мне эту ошибку:

error(65): csce322a1p2.g:70:24: unknown attribute 'cells' for rule 'partial_row' in '$partial_row.cells' 
+0

'locals []' ограничены одним правилом. 'returns []' использует тот же синтаксис, но эти объявления будут видны правилам вызова. Обратите внимание, что в ANTLR 4 больше ничего не рекомендуется в настоящее время, когда автоматически создаются пользовательские интерфейсы слушателей, которые доступны для разделения самой грамматики из другой логики, специфичной для языка. –

+0

@ 280Z28: Я не видел упоминания о прослушивании оружия. Не могли бы вы дать мне документацию для них? – Kevin

+0

Я имел в виду слушателей * и * посетителей, но я испортил ввод или мой телефон. Извини за это. –

ответ

0

Вместо locals, я хочу использовать @init и returns:

row returns [java.util.ArrayList<String> cells] 
    @init { 
    java.util.ArrayList<String> cells = null; 
    } 
    : partial_row RowSeparator 
    { 
    $cells = $partial_row.cells; 
    } 
    ; 

partial_row returns [java.util.ArrayListArrayList<String> cells] 
    @init { 
    java.util.ArrayListArrayList<String> cells = null; 
    } 
    : Cell 
    { 
    $cells = new java.util.ArrayList<String>(); 
    $cells.add($Cell.text); 
    } 
    | partial_row Cell 
    { 
    $cells = $partial_row.cells; 
    $cells.add($Cell.text); 
    } 
    ; 
0

Я думаю, что вы ищете «возвращает» не местных жителей. И это должно сработать. Мой тест работает:

Row местных жителей [ ArrayList клетки = нуль ] : A B { $ клеток = $ A; } ;

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