2012-10-24 45 views
0

我正在編寫一個編譯器,並且我有用於處理無限嵌套if語句的工作代碼,但它有點破解。我不知道這樣做是否安全?這是對Bison的安全編程嗎?

con_statement: 
IF exp DO 
{ 
    $1 = ifNum++; 
    if($2 == BOOLEAN_TYPE || $2 == INTEGER_TYPE) 
    { 
     utstring_printf(code, "\tpop\teax\n"); 
     utstring_printf(code, "\tcmp\teax, 0\n"); 
     utstring_printf(code, "\tje\tIF_END_%d\n", $1); 
    } 
    if($2 == FLOAT_TYPE) 
    { 
     utstring_printf(code, "\tnop\n"); 
    } 
} 
program FI 
{ 
    utstring_printf(code, "IF_END_%d:\n", $1); 
} 
; 
+0

你在擔心什麼?標籤生成?代碼生成?規則的「程序」部分?目前還不清楚你如何處理ELSE條款......也許這並不重要,但它通常是這樣。 –

+0

說$ 1 = LABELNUM並輸入終端對我來說似乎是一個糟糕的混亂?對不起,我忘了完成輸入, – SetSlapShot

+1

由於默認操作是設置'$$ = $ 1;',使用'$ 1'這樣的默認操作可能會產生分支上游,但它不應該影響Yacc代碼 - 只是您的任何操作看着'con_statement'返回的值。我認爲創建一種機制將標籤號與當前結構關聯起來更爲傳統。我認爲你在做的是非常規的。它認爲它可能會在以後對你產生影響。但我認爲它不會打破Yacc本身。 –

回答

1

這工作得很好,但是這將是國際海事組織更清晰的使用$$/$ 4:

con_statement: 
IF exp DO 
{ 
    $$ = ifNum++; 
    if($2 == BOOLEAN_TYPE || $2 == INTEGER_TYPE) 
    { 
     utstring_printf(code, "\tpop\teax\n"); 
     utstring_printf(code, "\tcmp\teax, 0\n"); 
     utstring_printf(code, "\tje\tIF_END_%d\n", $$); 
    } 
    if($2 == FLOAT_TYPE) 
    { 
     utstring_printf(code, "\tnop\n"); 
    } 
} 
program FI 
{ 
    utstring_printf(code, "IF_END_%d:\n", $4); 
} 
; 

第一個動作是生成一個值(它付諸$$),再到後來的行動能訪問該值。

交替(特別是如果你想支持ELSE),它可能是有意義的這一初步行動分離到單獨的生產:

con_statement: 
    if_head program FI 
    { utstring_printf(code, "IF_FALSE_%d:\n", $1); } 
| if_head program ELSE 
    { utstring_printf(code, "\tjmp\tIF_END_%d\n", $1); 
     utstring_printf(code, "IF_FALSE_%d:\n", $1); } 
    program FI 
    { utstring_printf(code, "IF_END_%d:\n", $1); } 
; 

if_head: 
    IF exp DO 
    { $$ = ifNum++; 
      : 
; 

這允許使用相同的操作對普通if和if/else語句,避免語法衝突,因爲在解析IF..DO時您不知道是否會有ELSE