Llvm yacc中的条件语句解析
我正在为某种语言编写一个llvm代码生成演示,其中包括if语句。以下是与我的问题相对应的规则和行动:Llvm yacc中的条件语句解析,llvm,yacc,llvm-clang,llvm-ir,llvm-gcc,Llvm,Yacc,Llvm Clang,Llvm Ir,Llvm Gcc,我正在为某种语言编写一个llvm代码生成演示,其中包括if语句。以下是与我的问题相对应的规则和行动: IfStatement : IF CondExpression THEN Statement {if_Stmt(string($2),string($4));} %prec LOWER_THAN_ELSE ; | IF CondExpression THEN Statement ELSE
IfStatement : IF CondExpression THEN Statement {if_Stmt(string($2),string($4));} %prec LOWER_THAN_ELSE ;
| IF CondExpression THEN Statement ELSE Statement {if_else_Stmt(string($2),string($4),string($6));}
;
CondExpression : Expression Relop Expression { $$ = operation($2,string($1),string($3));printf("Relop value : %s \n",$2);}
| Expression {$$ = $1;}
;
Relop : EE {$$ = (char *)(string("icmp eq ").c_str());printf("%s\n",$$);}
| NE {$$ = (char *)(string("icmp ne ").c_str());}
| LT {$$ = (char *)(string("icmp slt ").c_str());}
| GT {$$ = (char *)(string("icmp sgt ").c_str());}
| LTE {$$ = (char *)(string("icmp sle ").c_str());}
| GTE {$$ = (char *)(string("icmp sge ").c_str());}
;
CondExpression规则应该解析条件表达式。我正在使用print函数打印类型为 Relop value : 0
第二次内部重新打印的结果是正确的
Relop value : icmp eq
为什么CondExpression中的Relop值为0,以及如何使其采用从Relop规则返回的正确值。不仅是
(char *)(string("icmp ne ").c_str()
一种荒谬而混乱的写作方式
"icmp ne"
它还引入了简单而明显的替代方案中不存在的未定义行为。string
构造函数创建并返回一个临时字符串,然后使用c_str
返回指向该临时字符串的内部存储的指针。然后将该指针存储到解析器堆栈中,并对临时指针进行解构,从而孤立存储的指针。因此,当您试图打印字符串时,您正在传递一个悬空指针,任何事情都可能发生,例如,内存被重新用于其他对象,导致打印一个神秘的字符串
<>当然,如果你的语义类型是“代码> char */CODE >,C++将抱怨<代码> $$=ICMP EQ”;代码>不是常量安全的。我不清楚为什么不使用char*const
作为语义类型,除非代码的其他部分打算修改字符串或可能需要释放内存(因为在某些情况下字符串是动态分配的)。在这种情况下,您可以使用,例如,strdup
强制创建字符串的副本。如果您的库不提供strdup,或者您不想依赖它,那么可以很容易地将其定义为
char* strdup(const char* s, size_t len=strlen(s)) {
char* r = malloc(len + 1);
memcpy(r, s, len);
r[len] = 0;
return r;
}
虽然更像C++的解决方案是使用std::string*
作为语义类型,允许您编写:
$$ = new std::string("icmp eq");
您的语义类型是什么?CondExpression和reloppression的char*这是等于、不等于、小于、大于..等的字符串:。我要求找到一个解决方案,而不是创建一个problem@rational当前位置我理解字符串的含义。解决办法是解决我发现的问题。使用字符串文字或字符串文字的副本(如果出于某种原因需要副本),但不要创建悬空指针。