编写编译器:如何让简单模板工作
Writing a compiler: how to get simple templates to work?
我有一个语法非常像c++的语言。词法分析器和解析器已经就位并生成正确的AST。对于大部分后端也已经完成。
编译器用来创建类型的基本系统非常简单:所有类型都被认为是内置的,所有实例都是全局的。这里有一个简单的映射,它将一个类型名称匹配到一个创建变量的方法,它基本上是一个泛型类型,比如boost::any。另一个以变量名作为键,变量作为值的映射作为全局作用域:
std::map< std::string, std::function< Variable() > typeList;
//register some types
typeList[ "X" ] = Variable::Create<X>;
typeList[ "Y" ] = CreateInstanceOfY;
....
当编译器获得像X myVar;
这样的初始化的AST节点时,它基本上会
std::map< std::string, Variable > globalScope;
globalScope[ "myVar" ] = typeList[ "X" ]();
当稍后使用myVar时,它可以通过简单的类型调度来访问,如
X& x = myVar.GetReference<X>();
现在我想扩展一下,使用简单的模板。假设有一个类型"array",它是用vector实现的。我可以注册像
这样的东西typeList[ "array<X>" ] = Variable::Create< std::vector< X > >;
,但这不是很好管理,因为它必须在所有组合中重复。理想情况下,我需要允许这样写的功能:
typeList.CreateTemplateVariable( "array", "X" )
将创建一个变量实例,该实例内部保存一个std::vector
所以问题很简单:有可能这样做吗?以及如何?
我不确定我得到你的问题是正确的,但如果你有M参数类型(vector<>
, list<>
,…)和N个简单类型(int
, double
,…),你需要M*N实际实现,如果你想支持所有的组合。所有这些实现都必须在编译时知道(或者原则上可以动态调用c++编译器)。你真的想要这个吗?
一个解决方法是使用非类型容器。例如,vector<Object*>
存储指针,可以随后转换为所需的类型,例如使用dynamic_cast
。这样,您只需要M个参数类型的实现,并且可以独立地将"array"解析为vector
,将"X"解析为X
。
一般来说,您创建类模板类型的方法是按照您的描述,但不是提前创建所有可能的组合,而是根据需要创建它们。因此,您可能有一个getType
例程,如:
std::function< Variable() > getType(std::string name) {
auto rv = typeList[name];
if (rv) return rv;
auto template_start = name.find('<');
if (template_start != string::npos) {
auto template_end = name.rfind('>');
std::string arg = name.substr(template_start+1, template_end);
std::string base = name.substr(0, template_start);
typeList[name] = rv = InstantiateTemplate(base, arg);
return rv; }
throw UnknownTypeError(name);
}
对于程序中引用的任何类型都会调用该函数,根据需要创建所需的模板实例化。
- 一个非常简单的win32套接字代码,但工作错误
- 不使用与左右停止工作命名空间 std 的简单比较
- 让类与运算符一起工作更简单的方法
- 如何使用回调使工作变得简单按钮类?
- 简单的计数和求和函数没有按照我预期的方式工作
- C++编译器 g++.exe 无法编译简单的测试程序 - 确定 CXX 编译器是否工作失败
- 不明白为什么这个简单的递归开始工作然后崩溃
- 简单的 CPP 地图存储和访问无法按预期工作
- 简单的cin cout代码由"build and run"运行,但从bin/debug/x开始工作.exe
- 是否有任何简单的方法来查找当前的工作目录?C
- C++ 由于某种原因,我无法让模板在链表中工作,我敢打赌这是一个简单的错误,但我就是不明白
- 虽然这个简单的 C++ 程序可以打印 2 的幂,但它有很多问题时可以工作
- 为什么这个C++代码可以工作?(可能很简单)
- 简单的 if 和 else 语句无法正常工作
- 编写一个简单的函数,其工作方式与"std::cout"类似,但在末尾添加换行符
- 一个简单的程序,对数字进行计数和求和.我怎样才能让它工作
- 简单的 I/O 操纵器无法按预期工作
- 关于C++简单工作的问题
- GzipOutputStream和GzipInputStream与协议缓冲区的简单工作示例
- 运行时检查失败#0 - ESP值没有正确保存在…检查简单工作线程的点