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

Posted

技术标签:

【中文标题】来自文本字符串或其他机制的代码类自动生成器【英文标题】:An in code class auto generator from a string of text or some other mechanism 【发布时间】:2018-08-16 04:23:53 【问题描述】:

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

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

假设我有一个看起来像这样的文本文件:我上面的当前伪文件更长,并且有更详细的解释;但为简单起见,此处省略。如果您觉得需要,请不要犹豫,我会发布。

脚本

// 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>

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

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

我不确定的是:假设我在&lt;class:"Foo"&gt; 中阅读的部分,这将告诉我的解析器我想要一个名为Fooclass,这将是它的外壳:

class Foo ; 

正如预期的那样,但是我们还不能写出结尾的; 部分,因为我们还没有到达&lt;end:class&gt; 部分。所以此时我们需要写出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 的字符串。是否可以使用某种已经内置的功能在此处附加所需的文本以在代码中自动生成一个类而无需输入它?我不确定如何从字符串中提取文本以将其用作类名称的标识符。


结论

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

【问题讨论】:

"这里的问题是在关键字之后..." 不清楚。这是您正在解析自己的类似 xml 的文件的人。与编译器无关。 @liliscent 那是我遇到问题的部分;我不知道如何从字符串中提取文本以将其用作类名的标识符。 也许可以复习一些解析技术(这个案例很基础)... @liliscent 这不是解析部分的问题;它在 c++ 本身内。如果我在 while 循环或递归函数中,并且我想自动生成一个使用字符串中的文本作为其标识符的类的部分;这就是我不知道该怎么做。我在网上搜索过,但找不到太多可以帮助我的东西。 不,它与 C++ 无关。您想从自己的格式生成 C++ 源代码。无论哪种语言都可以完成这项任务,例如 Python。这里 C++ 不是一种编程语言,它是一些文本。 【参考方案1】:

抱歉,这不是 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(许多 Unix 风格,包括 Linux)或 LoadLibrary(Windows)。对于编译步骤,这意味着您运行程序的任何计算机都需要安装编译器,并且它可能应该是与您用于编译程序的编译器版本相当接近的版本。如果这个编译器在一个特殊的路径上,你的程序将如何被告知该路径?

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

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

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

【讨论】:

我不确定它是否可以完成,但我最初的假设是否定的。

以上是关于来自文本字符串或其他机制的代码类自动生成器的主要内容,如果未能解决你的问题,请参考以下文章

通过连接来自其他文本字段的字符串值自动填充访问表单中的字段

Android 自动生成的R类

自动生成器 -原创文章生成器在线版

来自数组 JS 的自动完成输入表单

bzoj1030: [JSOI2007]文本生成器(AC自动机+DP)

代理静态动态