我有一个创建AST的ANTLR语法,然后我编写了两个树语法,它们创建了树解析器,用于在AST上进行两次传递以进行语义分析.(之后我再做一次传递并使用StringTemplate生成输出代码)
到目前为止一切正常,但我试图扩展语言以支持函数中的参数多态(虽然到目前为止它只支持"简单"函数).
所以例如我想要这样的东西:
T getMax<T> (T a, T b) {
if (a > b) return a;
return b;
}
Run Code Online (Sandbox Code Playgroud)
并根据调用函数的实际类型生成简单的非参数多态代码.例如,如果有人调用,getMax<int> (5)那么我将只生成int的代码getMax(int a, int b)
到目前为止,在第一遍中,我检查了对多态函数的所有调用,并保存调用函数的特定类型.
所以,在这一点上,我知道所有参数类型,以及它们需要替换的所有实际类型.
在第二遍中,我想实际修改我的语法树并用一个或多个具有特定类型的函数声明替换这个参数化多态函数声明.
所以,问题是
在AST中复制和创建"兄弟"节点(以及所有子节点)的最佳方法是什么,并将它们插入到原始函数声明旁边?我只想说些什么
{
myTreeNode.parent.addChild(myTreeNode.dupNode());
}
Run Code Online (Sandbox Code Playgroud)在上例中T,int在新创建的子树中替换所有类型的最佳方法是什么?我认为一个简单的重写规则是不够的,因为我还需要替换函数体中的所有类型.我是否需要编写另一个仅在此函数声明子树上工作的树语法并进行所有替换?手动操作更容易吗?
对不起,如果这太混乱了.
编辑:
让我们说你的输入是这样的:
Run Code Online (Sandbox Code Playgroud)T add<T> (T a, T b) { return a+b } add<int>(1, 2) add<string>('f', 'oo')在第二次传球后你的AST会怎么样?
我想删除原始的函数声明,并在其位置引入2个专门的声明.
因此,生成的AST将是一个根节点(我们可以称之为"程序"),包含4个子节点,2个函数延迟和2个函数调用.
印花Lisp风格:
(METHOD_DECL int add (ARG_DECL int a) (ARG_DECL int b) (BLOCK (return (EXPR (+ (EXPR a) (EXPR b))))))
(METHOD_DECL …Run Code Online (Sandbox Code Playgroud) antlr ×1