2012-10-03 64 views
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.什么是笔者的意思是“不来构建抽象的树explictily” ? 2.我只需要了解上面的语法规则,它在做什么?由于我不是设计语言,我必须了解模式。如果我对上面的例子有了很好的理解,我可以有效地遵循模式?

感谢您的时间和帮助。

回答

0

这个例子看起来像来自像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”表达式。

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

1

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

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

同样是关于编译器。它得到你的源代码,经过几次随后的转换,你将得到一个可执行文件。这对于管道模式来说是非常好的示例,但可能没有这样的细节可能会让您从主要问题中分心。

1

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

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

作者指出的主要问题是调用“下一个”编译阶段,SA和CG在解析阶段被调用。换句话说,它不会等待整个解析器树“在执行语义分析和代码生成之前”生成。