2017-01-12 10 views
0

if文を含む特定の言語のllvmコード生成デモを書いています。yaccで条件文を解析する

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ルールは、条件式を解析する必要があります。私は印刷機能を使用して、< char *>タイプのRelopトークンの値を表示しています。 Relopは、上のコードのように、文字列関数内に条件付きトークンの値を持つ必要があります。しかし、印刷機能の結果は0

Relop value : 0 

あるとCondExpressionでRELOP値が0で、それを作るためにどのように、なぜRELOP内側の第二の印刷の結果は、

Relop value : icmp eq 

正しいですかRelopルールから返された正しい値を取る。

+0

セマンティックタイプとは何ですか? – rici

+0

char * CondExpressionとRelopの両方について –

答えて

1

だけでなく、それはまた、シンプルかつ明白な代替に存在していない未定義の動作を紹介し

"icmp ne" 

を書くばかばかしいほど難読化された方法

(char *)(string("icmp ne ").c_str() 

です。 stringコンストラクタは、一時的な文字列を作成して返します。そしてc_strは、その一時的な内部ストレージへのポインタを返すために使用されます。次に、そのポインタをパーサースタックに格納し、一時的なものを分解して、格納されたポインタを孤立させます。だから文字列を印刷しようとすると、ぶら下がっているポインタを渡してしまい、メモリが不思議な文字列が印刷される他のオブジェクトのために再利用されるなど、何かが起こる可能性があります。

もちろん、セマンティックタイプがchar *の場合、C++は$$ = "icmp eq";がconst-safeではないと不平を言うでしょう。コードの他の部分が文字列を修正しようとしているか、またはメモリを解放する必要がある(文字列が動的に割り当てられることがあるため)必要がある場合を除いて、意味タイプとしてchar *constを使用しない理由はすぐわかりません。この場合、たとえば、strdupを使用して文字列のコピーを強制することができます。解決策のようなセマンティック型としてstd::string*を使用することです - あなたのライブラリがstrdupを提供していないか、あなたがそのに依存したくない場合は、よりC++のが、それは簡単に

char* strdup(const char* s, size_t len=strlen(s)) { 
    char* r = malloc(len + 1); 
    memcpy(r, s, len); 
    r[len] = 0; 
    return r; 
} 

のようなものとして定義することができます

$$ = new std::string("icmp eq"); 
+0

これらは等しい、等しくない、より小さい、より小さい..etc:http://releases.llvm.org/2.7/docs/LangRef.htmlの文字列です。私は問題を作成しない解決策を見つけるように頼んだ。 –

+1

@rational:文字列の意味を理解する。解決策は、私が特定した問題を解決することです。文字列リテラルまたは文字列リテラルのコピーを使用してください(なんらかの理由でコピーが必要な場合)。しかし、ぶら下がりポインタは作成しないでください。 – rici