我希望* 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
答案 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:
诀窍是在重写规则中使用$addition
来引用整个规则本身。