yacc可以用于为Java 1生成三个地址代码吗?

问题描述 投票:0回答:1

我已经阅读过yacc为LALR(1)语法生成自底向上的解析器。我有一个Java 1语法,可用于生成三个地址代码,严格来说是LALR(1),但是我采用的翻译方案使其具有L属性。现在,我了解到在自下而上的解析过程中无法翻译L归因的LR语法。那么,可以在这里使用yacc吗?如果是的话,yacc如何解决这个问题?

java compiler-construction yacc lalr intermediate-code
1个回答
0
投票

除非您提出具体,详细的问题,否则您不会得到很好的答案。这是一个模糊的方法草图。

合成属性对于自下而上的解析器显然不是问题,因为它们是在相应终端的最终归约操作中计算的。因此,问题归结为“自下而上的解析器如何计算继承的属性?”

由于语法是L归因的,因此我们知道,任何继承的属性都是从其左同级的属性中计算出来的。 Yacc /野牛允许将动作插入到右侧的任何位置,并且这些"Mid-Rule Actions" (MRAs)被遇到时执行。一个MRA可以精确地使用它的左兄弟,因此这是计算继承属性所需要的全部。]

但是,这并没有显示该属性实际上是如何被继承的。在某些规则中,在语法符号前插入的MRA当然可以用于部分计算该符号的继承属性,但是继承属性也可以使用子元素的综合属性。

要实现这一点,我们需要做两件事:

  1. 在非终端之前插入MRA,该MRA收集左兄弟属性。由于MRA也是语法符号,因此该MRA将是最后一个左兄弟姐妹,实际上是终端孩子的最小叔叔。 (您不一定需要MRA;您可以插入“标记”:一个非终端,其唯一的输出为空,并且其动作是MRA主体。但这并不是那么方便,因为动作必须要达到语义。前面的语法符号的值。或者您可以将产生的内容分成两部分,这样两个动作都是最终的。)

  2. 访问终端的还原操作中的叔叔属性。

  3. Bison / yacc通过允许您使用非positibd符号索引来引用解析器堆栈中的插槽,从而允许第二步。特别地,$0指的是紧接在父代产品中非终结符之前的符号(我在上面称之为叔叔)。当然,要使其正常工作,您必须确保在出现非终端的每个产品中,叔叔是相同的非终端(或至少具有相同的语义类型)。这可能需要添加一些标记。

    说到语义值,您也许可以使自己满意,即给定非终结符的所有叔叔都是相同的,或者至少具有相同的类型。但是bison不会进行此分析,因此如果您弄错了它就不会警告您。小心!另一个后果是,您必须告诉野牛类型是什么,所以不能只写$0:需要$<tag>0

© www.soinside.com 2019 - 2024. All rights reserved.