Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 代码生成期间的宏替换_C++_Compiler Construction_Macros - Fatal编程技术网

C++ 代码生成期间的宏替换

C++ 代码生成期间的宏替换,c++,compiler-construction,macros,C++,Compiler Construction,Macros,目前,我有一些遗留代码,它生成操作代码。如果代码有更多的宏,那么代码生成将花费大量的时间(以小时为单位!!)。 我已经了解了逻辑,他们正在通过搜索宏并替换其中的每个变量(比如内联)来处理宏。 有没有一种方法可以在不操纵字符串的情况下对其进行优化?我有一个应用程序,它有自己的语法。它支持典型编译器支持的所有数据类型(甚至宏)。更确切地说,它是一种编译器,通过将程序(使用该语法编写)作为输入来生成操作码。 int c = a + b 为了处理宏,它使用文本替换逻辑 例如: int c = a +

目前,我有一些遗留代码,它生成操作代码。如果代码有更多的宏,那么代码生成将花费大量的时间(以小时为单位!!)。 我已经了解了逻辑,他们正在通过搜索宏并替换其中的每个变量(比如内联)来处理宏。

有没有一种方法可以在不操纵字符串的情况下对其进行优化?

我有一个应用程序,它有自己的语法。它支持典型编译器支持的所有数据类型(甚至宏)。更确切地说,它是一种编译器,通过将程序(使用该语法编写)作为输入来生成操作码。
int c = a + b
为了处理宏,它使用文本替换逻辑 例如:

int c = a + b
宏添加(a:int,b:int)

int c = a + b
结束宏

int c = a + b
//程序总和

int c = a + b

int c = a + b
int x=10,y=10

int c = a + b
加(x,y)

int c = a + b

int c = a + b
//节目结束

int c = a + b
更换后将是

int c = a + b
//程序总和

int c = a + b

int c = a + b
int x=10,y=10

int c = a + b
int c=x+y

int c = a + b

int c = a + b
//节目结束

int c = a + b
此文本替换占用了大量时间,即用宏逻辑替换宏调用。
有没有一种最佳的方法可以做到这一点?

如果不了解更多的预处理器/解析/编译过程,就很难回答这个问题。一个想法是将宏名称存储在符号表中。解析时,首先根据该表检查文本标记,如果找到匹配项,则将替换项写入新字符串,并通过解析器运行该字符串,然后在macrto的close Paren之后继续解析原始文本

int c = a + b

根据您的操作码语法,另一个想法可能是-当您在解析时遇到宏定义时,生成操作码,但将占位符放在参数的位置。然后,当解析器遇到对宏的调用时,生成用于计算参数的代码,并在预生成的宏代码中插入该代码来代替占位符。

在开始此类过程之前,您必须将输入标记化。(我推荐的著名版本还不够高——即使是古老的版本也经受住了时间的考验,2006年更新的版本看起来也很棒)。编译是一种最好分为更小阶段的工作:如果第一阶段将词法分析分为标记、将行分为关键字、标识符、常量等,那么查找宏的引用并在符号表中查找它们就简单得多。(使用lex或flex等工具或其现代等效工具为您完成这项工作也相对容易,而不是从头开始)

int c = a + b
“线索”似乎是,如果代码有更多的宏,那么代码生成会花费很多时间。这听起来像是宏数量的线性过程,这当然太多了。我假设这个过程一次只发生一行(如果您的语言允许的话,这显然有巨大的价值,因为您不需要将程序视为一个巨大的字符串),伪代码看起来像

int c = a + b
for(each line in the program)
{
    for(each macro definition)
    {
        test if the macro appears;
        perform replacement if needed;
    }
}
这显然与宏定义的数量成比例

int c = a + b
通过标记化,它看起来像这样:

int c = a + b
for(each line in the program)
{
    tokenize the line;
    for(each token in the line)
    {
        switch(based on the token type)
        {
            case(an identifier)
                lookup the identifier in the table of macro names;
                perform replacement as necessary;
            ....
        }
    }
}
这主要取决于程序的大小(而不是定义的数量)——符号表查找当然可以使用比遍历所有数据结构更优化的数据结构来完成,因此不再成为重要因素。第二步是类似yacc和bison(及其更现代的变体)的程序可以愉快地生成代码来完成的

int c = a + b

事后思考:解析宏定义时,也可以将其存储为令牌流,并标记作为参数替换的“占位符”名称的标识符。展开宏时,切换到该令牌流。(同样,像flex这样的东西也很容易做到)。

lol.你到底在说什么?什么宏、操作码和代码生成?什么字符串?你能举个例子让你的问题更容易理解吗?你在使用什么编译器,或者你指的是一些内部预处理器?建议添加标记“编译器”、“编译器理论”,并用这些标记检查其他问题。如果你把整个文件放在一个std::字符串中,因此,在一个大文件中替换宏需要花费时间也就不足为奇了。也许每行代码都是一个元素。替换是一个更复杂的过程,我想它会进行两次迭代。第一次迭代扫描宏,进行文本替换并构造树。在第二次迭代中,它通过将此树作为输入来生成操作码。
int c = a + b