yacc可以用来为Java1生成三个地址代码吗?

yacc可以用来为Java1生成三个地址代码吗?,java,compiler-construction,yacc,lalr,intermediate-code,Java,Compiler Construction,Yacc,Lalr,Intermediate Code,我已经读到yacc为LALR(1)语法生成自底向上的解析器。我有一个Java1语法,可以用于生成三个地址代码,严格来说是LALR(1),但我使用的翻译方案使其具有L属性。现在我已经读到,L属性的LR语法在自底向上解析期间无法翻译。那么,这里是否可以使用yacc?如果是的话,yacc是如何解决这个问题的?除非你提出一个具体、详细的问题,否则你不会得到一个好的答案。这里是一个方法的模糊草图 合成属性对于自底向上的解析器来说显然不是问题,因为它们是在对应终端的最终简化操作中计算的。所以问题归结为“自下

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

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

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

因为语法是L属性的,所以我们知道任何继承的属性都是从其左同胞的属性计算出来的。Yacc/bison允许在右侧的任何位置插入操作,并且 在遇到时执行。MRA可以精确地使用它的左同胞,因此这就是计算继承属性所需的全部内容

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

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

  • 在非终端之前插入一个MRA,该MRA收集了左侧同级属性。因为MRA也是语法符号,所以这个MRA将是最后一个剩下的兄弟姐妹,实际上是终端孩子的最小叔叔。(你不一定需要MRA;你可以插入一个“标记”:一个非终端,它唯一的产品是空的,它的动作是MRA主体。但这并不方便,因为动作必须获得前面语法符号的语义值。或者你可以将产品分成两部分,这样两个动作都是最终的。)

  • 在终端的还原操作中访问叔叔的属性

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

    说到语义值,您可以满足自己的要求,即给定非终结符的所有叔叔都是相同的,或者至少具有相同的类型。但是bison不做这种分析,所以如果你弄错了,它不能警告你。小心!另一个结果是,你必须告诉bison类型是什么,所以你不能只写
    $0
    :你需要
    $0

  • 注意:

    在L-属性化LR语法中处理继承属性并不总是可能的,因为在遇到非终结符的时刻,解析器可能还不知道非终结符实际上将构成解析树的一部分。这个问题在LL语法中不会出现,因为在LL解析中,解析器只能预测一个非终结符,如果其余输入有效,则该非终结符保证出现在解析中

    任何LL语法都可以自底向上解析,因此L属性的LL语法没有问题。但是自下而上的解析器可以做得更好;它不需要完整的语法。只有那些即将被分配继承属性的非终端的决策点才需要具有LL确定性

    这种限制是通过将MRA或标记放在非终端之前的技术来实现的。换句话说,在LR语法的某些点添加标记(或MRA)可能会使LR属性无效。关于这个问题的讨论在文章中进行得很好,所以我在这里不作详细阐述,只想观察一个细节

    上述用于传播继承属性的技术在战略点使用MRA(或标记)来保存继承属性。为了继续解析,必须减少这些结果,因此,正如《野牛手册》上述章节所述,可能需要重新安排语法以消除冲突。在极少数情况下,这种重写甚至是不可能的

    但是,删除冲突可能仍然会导致一种语法,在这种语法中,当某些非终端需要该值时,继承的属性会被传播,而不保证最终会减少非终端。在这种情况下,继承的属性将被不必要地计算,然后被忽略。但这不应该是个问题。属性概念中固有的概念是属性是功能性的;换句话说,计算没有副作用

    没有副作用意味着属性语法分析器应该可以自由地按照尊重属性依赖性的任何顺序计算属性。特别是,这意味着您可以通过将属性计算转化为连续,轻松实现正确的属性计算,这种技术有时被称为惰性计算或“thunking”

    但是,总是有人试图精确地使用MRA来产生副作用。一个非常常见的副作用是将三个地址代码打印到输出流中。另一个是变异持久数据结构,如符号表。这不再是L属性解析,因此这里提供的建议可能不适用于此类应用程序。

    “Java 1”?你是说Java 1.0,1月发布