树重写 - 整个子树而不仅仅是顶部节点应该成为根

发布于 2025-01-03 01:38:09 字数 2193 浏览 4 评论 0原文

我希望 *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(tree),我想要一个adaptor.dupTree(tree)。

给定输入

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

I want that the tree rewrite of *addition_operator* contains the whole subtree not only the top node, so that *hint_keywords* are still in the tree.

addition is so complex because I want to add the T_LEFT and T_RIGHT in the tree.

antlr 3.3

grammar:

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'
    ;

As far as I can see the reason is the implementation of RewriteRuleSubtreeStream#nextNode() which uses adaptor.dupNode(tree) and I want a adaptor.dupTree(tree).

given input

2 + [BIG] 3 - [FAST, THIN] 4

is:

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

and should be

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风情万种。 2025-01-10 01:38:09

试试这个:

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:

在此处输入图像描述

技巧是在重写规则中使用 $addition 来引用整个规则本身。

Try this:

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();};

which parses the input 2 + [BIG] 3 - [FAST, THIN] 4 + 5 into the following AST:

enter image description here

The trick was to use $addition in the rewrite rule to reference the entire rule itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文