Перезапись дерева - целое поддерево, а не только верхний узел, должно стать корневым - PullRequest
1 голос
/ 07 февраля 2012

Я хочу, чтобы дерево перезаписи * extension_operator * содержало целое поддерево, а не только верхний узел, чтобы * hint_keywords * все еще находились в дереве.

сложение настолько сложно, потому что я хочу добавить T_LEFT и T_RIGHT в дерево.

antlr 3.3

Грамматика:

grammar Test;

options {
    output = AST;
}

tokens {
    T_LEFT;
    T_RIGHT;
    T_MARKER;
}

@lexer::header {
    package com.spielwiese;
}

@header {
    package com.spielwiese;
}

NUM         :   '0' .. '9' ( '0' .. '9' )*;
ASTERISK    :   '*';
PLUS        :   '+';
MINUS       :   '-';
WS  :   (' '|'\r'|'\t'|'\n') {skip();};

addition
    :
        (a=atom -> $a)
        (
            addition_operator b=atom
            ->
                ^(addition_operator
                    ^(T_LEFT  $addition)
                    ^(T_RIGHT $b)
                )
        )+
    ;

atom
    :   NUM
    |   '(' addition ')' -> addition
    ;

addition_operator
    :   PLUS  hints? -> ^(PLUS  hints?)
    |   MINUS hints? -> ^(MINUS hints?)
    ;

hints
    : '[' hint_keywords += hint_keyword (',' hint_keywords += hint_keyword)* ']'
        ->
            $hint_keywords
    ;

hint_keyword
    :   'FAST'
    |   'SLOW'

    |   'BIG'
    |   'THIN'
    ;

Насколько я понимаю, причина в реализации RewriteRuleSubtreeStream # nextNode (), которая использует adaptor.dupNode (дерево), и я хочу adaptor.dupTree (дерево).

данный вход

2 + [БОЛЬШОЙ] 3 - [БЫСТРО, ТОЛЬКО] 4

есть:

              +---------+
              |    -    |
              +---------+
                   |    \
                   |     \
                T_LEFT  T_RIGHT
                   |       |
              +---------+
              |    +    |  4
              +---------+
                   |   \     
                 T_LEFT  T_RIGHT
                   |       |
                   2       3

и должно быть

              +---------+
              |    -    |
              +---------+
            /  /    |    \
           /  /     |     \
      FAST THIN  T_LEFT  T_RIGHT
                    |       |
               +---------+
               |    +    |  4
               +---------+
               /   |   \     
              /   T_LEFT  T_RIGHT
            BIG    |       |
                   2       3

1 Ответ

1 голос
/ 07 февраля 2012

Попробуйте это:

grammar Test;

options {
  output=AST;
}

tokens {
  T_MARKER;
  T_LEFT;
  T_RIGHT;
}

calc
 : addition EOF -> addition
 ;

addition
 : (a=atom -> $a) ( Add markers b=atom -> ^(Add markers ^(T_LEFT $addition) ^(T_RIGHT $b))
                  | Sub markers b=atom -> ^(Sub markers ^(T_LEFT $addition) ^(T_RIGHT $b))
                  )*
 ;

markers
 : ('[' marker (',' marker)* ']')? -> ^(T_MARKER marker*)
 ;

marker
 : Fast
 | Thin
 | Big
 ;

atom
 : Num
 | '(' addition ')' -> addition
 ;

Fast  : 'FAST';
Thin  : 'THIN';
Big   : 'BIG';
Num   : '0'..'9' ('0'..'9')*;
Add   : '+';
Sub   : '-';
Space : (' ' | '\t' | '\r' | '\n') {skip();};

, который разбирает входные данные 2 + [BIG] 3 - [FAST, THIN] 4 + 5 на следующие значения AST:

enter image description here

Хитрость заключалась в том, чтобы использовать $addition в правиле перезаписи для ссылки на само правило в целом.

...