gpt4 book ai didi

compiler-construction - 变体转换系统

转载 作者:行者123 更新时间:2023-12-04 08:40:23 24 4
gpt4 key购买 nike

我写了一个变体类,它将用作动态语言的主要类型,最终将允许256种不同类型的值(标头是一个无符号字节,实际上只使用了20种)。我现在想实现类型之间的转换/转换。

我最初的想法是查找表,但是所需的大量内存使其难以实现。

有哪些选择?目前,我正在考虑其他人的研究和建议中的另外三种方法:


将类型分组为更大的子集,例如数字或集合或其他。
制作一个具有CanCast(from,to)和Cast(Variant)方法的转换接口,并允许将实现该接口的类添加到列表中,然后可以检查该列表是否有任何转换类可以进行转换。
与(1)相似,但要创建多个主类型,并且转换是从原始类型到主类型再到最终类型的两步过程。


最好的系统是什么?

编辑:我已经添加了赏金,因为我仍然不确定最好的系统,当前答案非常好,并且肯定得到了+1,但是肯定有人这样做并且可以说出最好的方法是什么。

最佳答案

我的系统非常“繁重”(很多代码),但是非常快,而且功能非常丰富(跨平台C ++)。我不确定您要走多远的设计,但这是我所做的最大工作:

DatumState-包含“类型”的“枚举”和本地值的类,该值是所有原始类型(包括void*)中的“联​​合”。此类与所有类型都没有关联,并且可以用于任何本机/原始类型和“引用” void*类型。由于“ enum”也具有“ VALUE_OF”和“ REF_TO”上下文,因此此类可以表示为“完全包含” float(或某种原始类型),或“ referencing-but-not-拥有” float(或某种原始类型)。 (我实际上有“ VALUE_OF”,“ REF_TO”和“ PTR_TO”上下文,因此我可以在逻辑上存储一个值,一个不能为空的引用或一个可以的指针)要么为空,要么为空,我知道我需要删除或不删除。)

Datum-完全包含DatumState的类,但扩展了其接口以适应各种“知名”类型(例如MyDateMyColorMyFileName等)。这些知名类型实际上是存储在void*成员内的DatumState中。但是,由于enum的“ DatumState”部分具有“ VALUE_OF”和“ REF_TO”上下文,因此它可以表示“ pointer-to-MyDate”或“ value-of-MyDate”。

DatumStateHandle-使用(众所周知的)类型(如MyDateMyColorMyFileName等)参数化的帮助程序模板类,这是Datum用来从该状态中提取状态的访问器,已知类型。默认实现适用于大多数类,但是任何具有特定访问语义的类都只会覆盖此模板类中一个或多个成员函数的特定模板参数化/实现。

Macros, helper functions, and some other supporting stuff-为了简化将众所周知的类型“添加”到我的Datum / Variant中,我发现将逻辑集中到几个宏中,提供一些支持功能(如运算符重载)并在其中建立其他约定非常方便我的代码。

作为此实现的“副作用”,我获得了很多好处,包括引用和值语义,所有类型的“ null”选项以及对所有类型的异构容器的支持。

例如,您可以创建一组整数并对它们进行索引:

int my_ints[10];
Datum d(my_ints, 10/*count*/);
for(long i = 0; i < d.count(); ++i)
{
d[i] = i;
}


同样,某些数据类型通过字符串或枚举建立索引:

MyDate my_date = MyDate::GetDateToday();
Datum d(my_date);
cout << d["DAY_OF_WEEK"] << endl;
cout << d[MyDate::DAY_OF_WEEK] << endl; // alternative


我可以存储项目集(本机)或 Datum集(包装每个项目)。无论哪种情况,我都可以递归“解包”:

MyDate my_dates[10];
Datum d(my_dates, 10/*count*/);
for(long i = 0; i < d.count(); ++i)
{
cout << d[i][MyDate::DAY_OF_WEEK] << endl;
}


有人可能会说我的“ REF_TO”和“ VALUE_OF”语义过大,但它们对于“集合展开”是必不可少的。

我已经用九种不同的设计完成了这个“ Variant”的工作,而我目前的工作是“最重的”(大多数代码),但是我最喜欢的那个(几乎是最快的,对象占用空间很小),而且我已淘汰其他八种设计供我使用。

我设计的“缺点”是:


通过访问对象
来自 static_cast<>()void*
(类型安全且相当快,但
需要间接访问;但,
副作用是设计支持
存储“ null”。)
编译时间较长,因为
公开的知名类型
通过 Datum界面(但是您
如果不使用,可以使用 DatumState
想要知名的类型API)。


无论您的设计是什么,我都建议以下内容:


使用“ enum”或其他内容
您的“类型”,与
“值”。 (我知道你可以压缩
他们成一个“ int”之类的东西
有一点包装,但这就是
存取缓慢,而且操作起来非常棘手
保持新类型
介绍。)
依靠模板或其他东西来集中操作,
特定类型的机制
(覆盖)处理(假设您要
处理非平凡类型)。


游戏的名称是“添加新类型时的简化维护”(或者至少对我而言)。就像一份优质的学期报告一样,如果您不断删除维护系统所需的代码(例如,尽量减少改编新类型所需的工作),那么重写,重写,重写以保持或增加功能是一个很好的主意。到现有的 Variant基础结构)。

祝好运!

关于compiler-construction - 变体转换系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5900740/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com