编写编译器:如何使简单的模板工作?

sti*_*ijn 8 c++ compiler-construction abstract-syntax-tree c++11

我有一种语言与C++类似的语法.词法分析器和解析器就位并产生正确的AST.对于最大的部分,后端也已完成.

编译器用于创建类型的基本系统非常简单:所有类型都被认为是内置的,所有实例都是全局的.因此,只有一个简单的映射,它将类型名称与创建变量的方法相匹配,该变量基本上是一个泛型类型,如boost :: any.另一个变量名称为key且Variable为value的映射用作全局范围:

std::map< std::string, std::function< Variable() > typeList;

  //register some types
typeList[ "X" ] = Variable::Create<X>;
typeList[ "Y" ] = CreateInstanceOfY;
....
Run Code Online (Sandbox Code Playgroud)

当编译器获得AST节点进行初始化时就像X myVar;它基本上一样

std::map< std::string, Variable > globalScope;
globalScope[ "myVar" ] = typeList[ "X" ]();
Run Code Online (Sandbox Code Playgroud)

当稍后使用myVar时,可以通过简单的类型调度来访问它

X& x = myVar.GetReference<X>();
Run Code Online (Sandbox Code Playgroud)

现在我想扩展一下并使用简单的模板.假设存在使用向量实现的类型"数组".我可以注册一切像

typeList[ "array<X>" ] = Variable::Create< std::vector< X > >;
Run Code Online (Sandbox Code Playgroud)

但这不是很可管理的,因为它必须对所有组合重复.理想情况下,我需要功能允许写这样的东西:

typeList.CreateTemplateVariable( "array", "X" )
Run Code Online (Sandbox Code Playgroud)

然后会创建一个内部包含std :: vector <X>的Variable实例.我努力了,但无法弄清楚如何做到这一点.也许我只是用简单的类型映射开始了错误的方式,这就是我无法理解它的原因.

所以问题很简单:是否可以这样做?如何?

Rom*_*n L 2

我不确定我是否正确地解决了您的问题,但是如果您有 M 个参数类型(vector<>, list<>, ...)和 N 个简单类型(int, double, ...),如果您想支持所有,则需要 M*N 实际实现组合。所有这些实现都必须在编译时已知(或者原则上您可以即时调用 C++ 编译器)。你真的想要这个吗?

解决方法可能是使用非类型化容器。例如,vector<Object*>存储随后可以转换为所需类型的指针,例如使用dynamic_cast. 这样,您只需要参数类型的 M 实现,并且可以独立地将“array”解析为vector,将“X”解析为X独立。