C++ 通过一些ASM代码包装函数指令

C++ 通过一些ASM代码包装函数指令,c++,c,compiler-construction,bison,yacc,C++,C,Compiler Construction,Bison,Yacc,我正在做一个简单的C编译器作为家庭作业。我有以下语法规则: function_definition : type_name declarator compound_statement 我的语义规则应将其转换为: declarator: push %ebp mov %esp %ebp // compound_statement (function instructions) pop %ebp ret 由于复合_语句规则将在函数_定义之前调用,因此我无法在其语义规则中直接

我正在做一个简单的C编译器作为家庭作业。我有以下语法规则:

function_definition
: type_name declarator compound_statement
我的语义规则应将其转换为:

declarator:
  push %ebp
  mov %esp %ebp

  // compound_statement (function instructions)

  pop %ebp
  ret
由于
复合_语句
规则将在
函数_定义
之前调用,因此我无法在其语义规则中直接调用
fprintf()
函数指令。但是,我也不能在Yacc类型中定义任何
streamstring
(请参阅:)

那么,我应该如何将函数指令放在字符串中(很容易,不要使用strcat,这在内存分配方面会很混乱),然后用前面的ASM指令包装它们呢

有两种方法:

  • 您可以在
    复合_语句
    规则的代码中构建包含函数体表示的对象,然后将其作为参数传递给
    函数_定义
    规则的代码,或者
  • 您可以将GNU扩展用于mid规则代码

    • 您可以将该规则写成:

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

      并继续直接使用复合_语句输出代码的规则。问题在于,根据语法的其他部分,这可能会引入移位/减少或减少/减少冲突,因为嵌入式操作在解析复合_语句之前会引入额外的空减少(以运行操作代码)。

      因此无法在
      复合_语句中获取子节点的输出?制作一个表示将非常困难…mid规则代码是一个标准的yacc特性,而不是GNU扩展。然而,使用它可以引入移位/减少或减少/减少冲突。您可以使用“生成输出的字符串”作为表示。这是Simon Ritcher对“中间规则”的建议,它似乎对我有效。