2012-01-19 40 views
0

我正在做一個簡單的C編譯器作爲作業。我有以下的語法規則:由一些ASM代碼包裝功能說明

function_definition 
: type_name declarator compound_statement 

我的語義規則應該將其轉化爲:

declarator: 
    push %ebp 
    mov %esp %ebp 

    // compound_statement (function instructions) 

    pop %ebp 
    ret 

由於compound_statement規則將前function_definition被稱爲,我不能fprintf()功能指令直接在它的語義規則。但是,我無法在Yacc類型中定義任何streamstring(請參閱:my previous question)。

那麼我應該如何將函數指令放入一個字符串中(很容易,不會使用strcat這會在內存分配方面造成混亂),然後用前面的ASM指令來包裝它們?

回答

1

你或許可以寫規則爲:

function_definition: 
    type_name declarator 
     { fprintf(..function prefix code..); } 
    compound_statement 
     { fprintf(..function suffix code..); } 
; 

,並繼續直接對compound_statement輸出代碼的規則。問題在於,根據語法的其他部分,這可能會引入shift/reduce或reduce/reduce衝突,因爲嵌入的操作在解析compound_statement之前引入了額外的空值減少(用於運行操作碼)。

+0

這就是Simon Ritcher建議的「中等規模」,它似乎對我有用。 –

0

有兩種方式:

  • 您可以構建一個包含了compound_statement規則,然後將其作爲參數傳遞給function_definition規則的代碼,通過代碼內的函數體的表現對象,
  • 您可以將GNU擴展用於中間規則代碼。
+0

所以沒有辦法在'compound_statement'中獲取子節點的輸出?做一個表示將是非常困難的... –

+0

中規則代碼是一個標準的yacc功能,而不是一個GNU擴展。但是,使用它可以引入轉換/減少或減少/減少衝突。 –

+0

您可以使用「帶有生成輸出的字符串」作爲表示。 –