Tree Rewrite - 整个子树不仅仅是顶级节点应该成为root

时间:2012-02-07 13:59:35

标签: antlr antlr3

我希望* addition_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 + [BIG] 3 - [FAST,THIN] 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 个答案:

答案 0 :(得分:1)

试试这个:

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来引用整个规则本身。