来自文本字符串或某种其他机制的代码类自动生成器

An in code class auto generator from a string of text or some other mechanism

本文关键字:机制 代码 自动生成 其他 文本 字符串      更新时间:2023-10-16

如果可能的话,我希望能够在代码中自动生成一个类。

我知道我可以有一个可以打开的文本或脚本文件,并将该文件的内容加载到字符串向量或字符串流中,然后从那里写回一个文件或一组文件以生成一个类。我对解析方面的细节不感兴趣,这不是我实际追求的。

假设我有一个文本文件,看起来像这样:我上面的当前伪文件要长得多,有更详细的详细解释;但为了简单起见,这里省略了。如果您觉得需要它,请随时询问,我会发布它。

脚本

// The finalized scripting file & its parser will not have any comments within code sections.
// Comments can be found before & after the <begin:file> & <end:file> sections
// This is the beginning of the file and whether or not a header and or cpp file
// is generated or not. If not then the idea is to generate the class in code directly.
// <begin:file "Foo.h"> // header only otherwise 
// <being:file "Foo.h", "Foo.cpp"> for both header and cpp 
<begin:file> 
<class:"Foo">
<private:>
<variables: int=mX,mY,mZ float=mWidth,mHeight>
<public:>
<constructor:defualt=t, init=t>
<constructor:copy=t> // automatically generates both copy() & operator=() as = default;
<constructor:copy=f> // declares both copy() & operator() as = delete;
<destructor:default=t>
<end:class>
<end:file>

在上面的脚本中,我<begin:file>,因为它后面没有字符串;这意味着我不想写入文件来创建头文件和/或 cpp 文件。由于省略了它们,我想在代码中生成这个类。

我不想诉诸使用macros.如果可能的话,我可以使用模板或其他机制。

我不确定的是:假设我在我读到的部分,<class:"Foo">这将告诉我的解析器我想要一个名为Fooclass,这将是它的 shell:

class Foo {}; 

然而,正如预期的那样,我们还不能写出结尾};部分,因为我们还没有到达<end:class>部分。所以在这一点上我们需要写出class Foo {,我在这里看到的部分或问题是我不知道我如何能够获取文本或字符串,例如std::string name("Foo");并在c++关键词class之后附加。伪示例:

{
std::string name("Foo");
class name {
public:
int x; 
};
std::cout << name << std::endl; // compiles and prints to the console "Foo"
std::cout << name.y << std::end; // will not compile.
}

这里的问题是,在c++的关键字class之后,它需要一个标识符,编译器不会接受这一点。编译器将声明一个名为name的字符串,该字符串的内容为"Foo",然后在下面尝试使用该字符串声明类时,它看不到带有标识符名称的类的字符串和名称。然后,如果您之后尝试使用该类,它根本找不到该类,而是找到名为 name 的字符串。是否可以使用某种已经内置的功能在此处附加所需的文本,以便在代码中自动生成类而无需键入它?我不确定如何从字符串中提取文本以将其用作类名称的标识符。


结论

通过阅读我的相关问题中提供的评论和答案;然后它证明了我最初的假设,我没有提到是正确的。这是做不到的。这确实需要从解析器的角度来看将类写入各自的文件。

抱歉,这不是C++的工作方式。 编译器理解关键字class和成员名称之类的东西,并且通常将所有理解用于将所有内容转换为机器代码,机器代码通常只使用大量原始指针和偏移量,而不是成员名称或类似的东西。 只有在编译器完成后,您才能运行程序,而典型的程序本身根本不包含太多理解类、成员名称或赋值运算符等内容的功能。

那么你有什么选择呢? 您可以编写一些实用程序,这些实用程序能够执行常规类将执行的某些操作,但您将无法以编译器从程序中的头文件中了解的类相同的方式引用它。 这可能看起来像这样:

{
CustomClass myclass( "Foo.cls" );
CustomObject obj = myclass.create(); // default constructor
CustomObject obj_copy = obj; // copy constructor
}

或者你可以做一些在运行时编译和加载插件的事情,尽管尝试这样做有一些复杂性。 这仍然不允许你使用自定义类,就像编译到你的程序中一样,但它允许任意C++代码(这既强大又危险,因为有人可能会意外或恶意地破坏任何内容)。 这将涉及将配置文件转换为您写出的实际临时C++源文件,使用特殊选项运行编译器以创建"共享库"(Unix,包括Linux)或"DLL"(Windows),然后使用dlopen(包括Linux在内的许多Unix风格)或LoadLibrary(Windows)加载该库。 对于编译步骤,这意味着运行程序的任何计算机都需要安装编译器,并且它可能应该是与您用于编译程序的编译器版本相当接近的版本。 如果此编译器位于特殊路径上,则如何告知您的程序该路径?

另外,您需要设计一个插件架构,考虑以下因素:

  • 插件如何与程序接口? 它是否提供了一个只输入和输出字符串向量的函数? 它是否提供了一个函数来创建从某个抽象基类派生的类对象?

  • 如果插件需要使用特定于程序的任何基类或专用函数,您将如何确保在编译插件时向编译器提供所需的头文件?