2012-02-07 54 views
1

我希望* 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(树)的实施,我想一个适配器。 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

试试:

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

+1

谢谢您的回答!它很好地解决了这个问题!但T_MARKER仅仅是更复杂子树的一个例​​子。在你的解决方案中,你正在设置T_MARKER。我需要一个子树的通用解决方案。 – ollins 2012-02-07 17:37:41

+0

示例增强 – ollins 2012-02-07 18:20:14

+0

不客气@ollins。 – 2012-02-07 19:15:56