【问题标题】:Wrap function instructions by some ASM code通过一些 ASM 代码包装函数指令
【发布时间】:2012-01-19 20:17:02
【问题描述】:

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

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 指令包装它们?

【问题讨论】:

    标签: c++ c compiler-construction bison yacc


    【解决方案1】:

    你可以把这条规则写成:

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

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

    【讨论】:

    • 这就是 Simon Ritcher 建议的“中间规则”,它似乎对我有用。
    【解决方案2】:

    有两种方式:

    • 您可以在compound_statement 规则的代码中构建一个包含函数体表示的对象,然后将其作为参数传递给function_definition 规则的代码,
    • 您可以将 GNU 扩展用于中间规则代码。

    【讨论】:

    • 所以没有办法在compound_statement 中获取子节点的输出?做代表会很困难......
    • 中间规则代码是标准的 yacc 功能,而不是 GNU 扩展。但是,使用它可能会引入 shift/reduce 或 reduce/reduce 冲突。
    • 您可以使用“带有生成输出的字符串”作为表示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多