我有一条要拆分的规则,因为我也想在其他规则中重复使用相同的子规则。原始版本工作正常:
type
: ( basicType -> basicType )
( '*' -> ^(TYPE_POINTER basicType)
| '[' ']' -> ^(TYPE_DYN_ARRAY basicType)
| '[' IntegerLiteral ']' -> ^(TYPE_STATIC_ARRAY IntegerLiteral basicType)
| '[' IntegerLiteral '..' IntegerLiteral ']' -> ^(REF_TYPE_SLICE IntegerLiteral IntegerLiteral basicType)
| '[' type ']' -> ^(TYPE_MAP_ARRAY type basicType)
)?
;
这条规则可以将一个普通类型(basicType,它可以是引用或主要类型,如 int、char 等)放在不同的 AST 节点下,使其成为指针、数组等。这在类似 C 的语言中很常见。
但是,如果我这样拆分:
basicType2
: '*' -> ^(TYPE_POINTER)
| '[' ']' -> ^(TYPE_DYN_ARRAY)
| '[' IntegerLiteral ']' -> ^(TYPE_STATIC_ARRAY IntegerLiteral)
| '[' IntegerLiteral '..' IntegerLiteral ']' -> ^(REF_TYPE_SLICE IntegerLiteral IntegerLiteral)
| '[' type ']' -> ^(TYPE_MAP_ARRAY type)
;
type
: ( basicType -> basicType )
( basicType2 -> ^(basicType2 basicType) )?
;
一切看起来都很好,解析不会受到影响,但是在 AST 中,basicType2 的孩子完全丢失了。在 TYPE_STATIC_ARRAY、REF_TYPE_SLICE 或 TYPE_MAP_ARRAY 的情况下,只会将根复制到类型之上,但缺少子节点。
我调试了解析器代码,在我看来,CommonTree 类的复制构造函数在不复制子项时调用,只有令牌和源范围信息。有没有办法通过重写规则将 CommonTree 节点及其子节点带到另一个节点的顶部?