管道和过滤器结构



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

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

在这里,作者提到了前端阶段,如解析器、语义分析、中间代码生成。后端是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.我只需要理解上面的语法规则它在做什么?由于我不是在设计车道,所以我必须了解图案。如果我对上面的例子有很好的理解,我能有效地遵循这个模式吗?

谢谢你的时间和帮助。

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

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

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

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

  • sa.checkCompat指的是-语义分析器,Check两个操作数的兼容性
  • cg.genAdd指的是-Code Generator,生成代码将两个操作数相加

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

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

你发布的"代码"告诉一种叫做"addexpr"的表达式类型的语法规则。

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

这读起来像:

加法表达式是一个术语或另一个加法表达式+一个术语或者另一个相加表达式-一个术语。

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

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

最新更新