Tree Antlr:转换规则右侧的匹配输入

Tree Antlr:转换规则右侧的匹配输入,tree,antlr,Tree,Antlr,我正在尝试编写一个语言解析器并构建一个漂亮的AST。在语言中,函数本质上是一个具有可调用值的变量。例如: int f(int arg) {...}; #int(int) f: int(int arg) {...}; 两者都是相等的,我想把第一个转换成第二个。如您所见,变量的类型包含参数,但没有名称。函数值需要参数名 所以问题是:是否可以从匹配参数列表的规则中同时获取(int arg)和(int),或者是否可以将->右侧的第一个转换为第二个 我将在下面添加一个示例源和结果树 Input: ^(F

我正在尝试编写一个语言解析器并构建一个漂亮的AST。在语言中,函数本质上是一个具有可调用值的变量。例如:

int f(int arg) {...};
#int(int) f: int(int arg) {...};
两者都是相等的,我想把第一个转换成第二个。如您所见,变量的类型包含参数,但没有名称。函数值需要参数名

所以问题是:是否可以从匹配参数列表的规则中同时获取
(int arg)
(int)
,或者是否可以将
->
右侧的第一个转换为第二个

我将在下面添加一个示例源和结果树

Input:
^(FUN_DEF
  ^(TYPE_SIMP 'int')
  'f'
  ^(PARAM_LIST
    ^(PARAM 'int' 'arg')
   )
  ^(BLOCK ...)
 )

Result:
^(VAR_DEF
  ^(TYPE_FUN
    ^(TYPE_SIMP 'int')
    ^(PARAM_LIST
      ^(PARAM 'int')
     )
   )
  'f'
  ^(FUN
    ^(TYPE_SIMP 'int')
    ^(PARAM_LIST
      ^(PARAM 'int' 'arg')
     )
    ^(BLOCK ...)
   )
 )

一种可能是在
shortFunction
规则中调用一个自定义方法,给定
paramList
,该方法将从它们中除去所有标识符,只留下类型并将该树插入正确的位置:

shortFunction
  :  type ID '(' paramList ')' block 
     -> ^( ... {customMethod($paramList.tree)} ... )
  ;
演示:

文件:Fun.g
语法乐趣;
选项{
输出=AST;
ASTLabelType=CommonTree;
}
代币{
根;
PARAM;
参数列表;
块
VAR_DEF;
乐趣;
类型_-FUN;
SIMP型;
}
@解析器::成员{
私有CommonTree条带ID(CommonTree树){
CommonTree副本=新CommonTree(新CommonToken(参数列表,“参数列表”);
对于(int i=0;i^(根函数+)
;
功能
:短功能
|长函数
;
短函数
:type ID“(“paramList”)”块
->^(VAR_DEF^(TYPE_FUN^(TYPE_SIMP TYPE){stripIDs($paramList.tree)})ID^(FUN^(TYPE_SIMP TYPE)paramList块))
;
长函数
:'#'t1=type'('typeList')'ID':'t2=type'('paramList')'块
->^(VAR_DEF^(TYPE_FUN^(TYPE_SIMP$t1)类型列表)ID^(FUN^(TYPE_SIMP$t2)参数列表块))
;
参数列表
:(参数(','param)*)?->^(参数列表参数*)
;
param
:类型ID->^(参数类型ID)
;
类型表
:(类型(','类型)*)?->^(参数列表^(参数类型)*)
;
类型
:INT
|短
|字节
;
块
:“{''''''}'->^(块'''''''))
;
短:“短”;
字节:“字节”;
INT:‘INT’;
ID:('a'..'z'.'a'.'z')('a'.'z'.'a'.'z'.'0'.'9')*;
空格:(“”|’\t’|’\r’|’\n’{$channel=HIDDEN;};
文件:Main.java 如果运行main类,您将看到输入:

#short(byte, int) f: short(byte a, int b) { ... } 
short f(byte a, int b) { ... }
生成两个相同的树:


一种可能性是在
shortFunction
规则中调用一个自定义方法,给定
参数列表
,该规则将从它们中除去所有标识符,只留下类型并将该树插入正确的位置:

shortFunction
  :  type ID '(' paramList ')' block 
     -> ^( ... {customMethod($paramList.tree)} ... )
  ;
演示:

文件:Fun.g
语法乐趣;
选项{
输出=AST;
ASTLabelType=CommonTree;
}
代币{
根;
PARAM;
参数列表;
块
VAR_DEF;
乐趣;
类型_-FUN;
SIMP型;
}
@解析器::成员{
私有CommonTree条带ID(CommonTree树){
CommonTree副本=新CommonTree(新CommonToken(参数列表,“参数列表”);
对于(int i=0;i^(根函数+)
;
功能
:短功能
|长函数
;
短函数
:type ID“(“paramList”)”块
->^(VAR_DEF^(TYPE_FUN^(TYPE_SIMP TYPE){stripIDs($paramList.tree)})ID^(FUN^(TYPE_SIMP TYPE)paramList块))
;
长函数
:'#'t1=type'('typeList')'ID':'t2=type'('paramList')'块
->^(VAR_DEF^(TYPE_FUN^(TYPE_SIMP$t1)类型列表)ID^(FUN^(TYPE_SIMP$t2)参数列表块))
;
参数列表
:(参数(','param)*)?->^(参数列表参数*)
;
param
:类型ID->^(参数类型ID)
;
类型表
:(类型(','类型)*)?->^(参数列表^(参数类型)*)
;
类型
:INT
|短
|字节
;
块
:“{''''''}'->^(块'''''''))
;
短:“短”;
字节:“字节”;
INT:‘INT’;
ID:('a'..'z'.'a'.'z')('a'.'z'.'a'.'z'.'0'.'9')*;
空格:(“”|’\t’|’\r’|’\n’{$channel=HIDDEN;};
文件:Main.java 如果运行main类,您将看到输入:

#short(byte, int) f: short(byte a, int b) { ... } 
short f(byte a, int b) { ... }
生成两个相同的树:


嗯。。。您的shortFunction似乎假设这里只有一个函数参数,并且类型等于返回类型:
^(PARAM_LIST type)
假设存在
int f(short arg)
int f(int arg1,int arg2)
,则
type_FUN
将只有一个参数。那么-如何从我的乐趣中获得
(int,int)
(int arg1,int arg2)?很抱歉延迟反馈,我似乎未能正确激活通知:S@Silly怪胎,看看我修改过的答案。谢谢!这就是我一直在寻找的。我希望有一种非java的、只有antlr的方式,但我想这是非常好的。特别感谢您提供的提示,
{java();}
在右侧是可能的,以及如何使用java正确转换树的示例@愚蠢的怪胎,不客气。但是,请注意,在本例中是
{java()}
,而不是
{java();}
。。。您的shortFunction似乎假设这里只有一个函数参数,并且类型等于返回类型:
^(PARAM_LIST type)
假设存在
int f(short arg)
int f(int arg1,int arg2)
,则
type_FUN
将只有一个参数。那么-如何从我的乐趣中获得
(int,int)
(int arg1,int arg2)?很抱歉延迟反馈,我似乎未能正确激活通知:S@Silly怪胎,看看我修改过的答案。谢谢!这就是我一直在寻找的。我跳