向标准C语法添加关键字

向标准C语法添加关键字,c,gcc,clang,C,Gcc,Clang,我正在考虑一个源代码到源代码的编译器,它想在标准C语法中添加一个关键字(比如说shared)。当指针被标记为共享时,它是一个特殊的指针,不能直接取消引用。相反,应该进行函数调用以安全地复制该值 如果所有变量都是原始类型,那么一个简单的C++程序就可以为我翻译。然而,我们有struct和union,还有一些可能性,比如struct包含共享指针,struct包含指向共享指针的简单指针,等等。这听起来像是一个严肃的类型检查,就像处理volatile关键字一样,可能重用或修改现有编译器会是一个更好的选择

我正在考虑一个源代码到源代码的编译器,它想在标准C语法中添加一个关键字(比如说shared)。当指针被标记为共享时,它是一个特殊的指针,不能直接取消引用。相反,应该进行函数调用以安全地复制该值

<>如果所有变量都是原始类型,那么一个简单的C++程序就可以为我翻译。然而,我们有struct和union,还有一些可能性,比如struct包含共享指针,struct包含指向共享指针的简单指针,等等。这听起来像是一个严肃的类型检查,就像处理volatile关键字一样,可能重用或修改现有编译器会是一个更好的选择。但我不知道哪个编译器更容易开始修改。你有什么建议吗?顺便说一下,我想看看翻译后的C代码,而不是中间代码。它会改变我们的选择吗?谢谢。

我们的its可能是合适的

DMS提供通用解析/AST构造、符号表构造、控制和数据流分析设施、用于AST修改的过程API和表面语法重写规则,以及AST到可编译文本的重新生成(包括注释重新生成)。前端将DMS专门化为一种特定的语言(例如,C;DMS支持许多其他语言)。前端由BNF驱动;一切都建立在这之上(使用属性语法等)。方言管理使语言前端能够专用于特定方言(对于C,目前包括GCC2/3/4、MS Visual C、ANSI C、GreenHills C、C99等)

为了执行OP的任务,他将为他的C版本定义一种方言,修改前端提供的符号表机制以捕获指针的新属性,并修改类型检查以验证新指针类型没有被他的定义误用。通过类型检查,他可以编写源代码到源代码的转换,将共享ptrC转换为香草C,以获得可运行的代码

替代方法可能是使用Clang或GCC,但我的理解是两者都没有语法,因此对解析器的更改必须作为代码实现。两者都不提供任何源到源的重写。我认为Clang提供了源代码修补,但我不确定一旦修补,您是否可以对某个地方应用一系列重写。我认为GCC可以让您按程序修改AST,但不能重新生成源代码


所有这些解决方案在预处理方面都存在一些问题。我认为Clang和GCC必须扩展预处理器指令。DMS必须扩展非结构化指令。

您知道不透明类型吗?在
.h
文件中声明类型:

typedef struct OpaqueType_s OpaqueType;
struct OpaqueType_s {
   int value;
};
并在
.c
文件中定义它:

typedef struct OpaqueType_s OpaqueType;
struct OpaqueType_s {
   int value;
};
然后,您可以在
.c
文件中取消引用指向它的指针,其中 您可以定义它,但只能将它们传递给其他文件中的其他函数
(有点像
void
)。

您如何标记负责取消引用每个指针的函数?@unwind:如果
shared
被视为发问者建议的cv限定符,那么您大概可以使用。对发问者:这并不能回答你的问题,但为什么不转发declare
struct shared\u Foo对于每种类型
Foo
您想要这个吗?然后,
shared\u Foo*
不能被取消订阅,但应该取消订阅的人会将其强制转换为
Foo*
。通常,当人们需要不透明的指针时,他们很高兴有一些TU可以使用它们,而另一些则不能。因此,他们甚至不需要
共享\u Foo
,只需在头文件中转发声明
结构Foo
,并在.c文件中定义它。“标准c语法”?实际上不存在:-{很多变体。至于关键字部分,我建议添加一个属性(和#定义你的“关键字”),这是一种更容易的方法。应该可以在clang级别实现你的分析,但使用中间代码(llvm ir)更容易,它本质上是一种转义分析。如果你跟踪(含元数据)你所有的指针都来自哪里,然后你可以将你的分析传播回AST级别,并发出转换后的代码。我们有一个点击并运行的投票者,他标记了答案,但没有提供关于投诉的评论反馈。我得到了很多这样的信息;我怀疑这是因为DMS的商业性质。虽然我知道有人可能有个人理由不使用商业产品,这似乎是一个不好的理由反对答案。