0

我正在阅读面向模式的软件架构中的管道和过滤器架构模式。在这里我不必知道编译器设计,但作者给出了编译器设计的例子。我遵循了大部分内容,但我很难理解以下内容。

在编译器设计中,我们有不同的阶段,如扫描器、解析器、语义分析、中间代码生成和后端(MIPS 后端、英特尔后端......)。

这里作者提到了前端阶段,解析器,语义分析,中间代码生成。后端是 MIPS 后端。

以下是文本片段

我们决定不显式地构造抽象语法树,将其从解析器传递到语义分析器。相反,我们将对语义分析器(sa)和代码生成器(cg)的调用嵌入到 yacc 的语法规则中:

addexpr  : team
         | addexpr '+' term
           { sa.checkCompat($1,$3); cg.genAdd($1,$3);}
         | addexpr '-' term
           { sa.checkCompat($1,$3); cg.genSub($1,$3);}

我对上述文本的问题 1. 作者所说的“不明确地构造抽象树”是什么意思?2.我只需要了解上面的语法规则它是做什么的?因为我不是设计语言,所以我必须了解模式。如果我对上面的例子有很好的理解,我可以有效地遵循模式吗?

感谢您的时间和帮助。

4

3 回答 3

1

我认为 Morten Jensen 回答了有关语法解释的问题。另外,我猜:

  • sa.checkCompat 指的是 - 语义分析器,检查两个操作数的兼容性
  • cg.genAdd 是指 - 代码生成器,生成代码以添加两个操作数

作者指出的主要内容是对编译的“下一个”阶段、SA 和 CG 的调用是在 Parsing 阶段中调用的。换句话说,它不会等到整个 Parser 树生成“之前”才进行语义分析和代码生成。

于 2012-10-06T06:20:52.690 回答
1

我相信@MortenJensen 回答了你的第一个问题。

如果你做过一些 Web 开发,可能你已经知道什么是管道。想象一下您在 Web 服务器上的请求处理。有一行独立的模块解析它们的输入(这是一行中前一个模块的输出),最后一个生成输出 http 响应。(tcp包转化为http请求,http请求转化为服务器对象,请求被解析并创建响应服务器对象,对象呈现为html,html包装成http响应,被包装到tcp包中)。

关于编译器也是如此。它获取您的源代码,经过几次后续转换,您将获得一个可执行文件。这是流水线模式的一个很好的示例,但可能没有这样的细节会分散你对主要问题的注意力。

于 2012-10-05T18:15:26.403 回答
0

这个例子看起来像来自像 yacc-lex/bison-flex 这样的词法解析器的语法规则。像您所描述的规则是一种分层语法规则,例如BNF

您发布的“代码”告诉了一种称为“addexpr”的表达式的语法规则。

addexpr := term | addexpr + term | addexpr - term

内容如下:

add-expression 是一个 term 或另一个 add-expression + term 或另一个 add-expression - term。

您可以使用这些递归语法规则来构建语言表示。代码{ sa.checkCompat($1,$3); cg.genAdd($1,$3);}看起来像是在对 $1 和 $3 进行输入验证 - 如在参数 1 和 3 中,“X + Y”中的 $1 将是 'X'、$2='+' 和 $3='Y'。调用cg.genAdd可能是一个函数调用,它将“add”表达式添加到您的抽象语法树中。

这意味着您在解析源代码时一次生成一个元素的抽象语法树。

于 2012-10-03T13:52:50.307 回答