六七章总结

1、属性文法
  是在上下文无关文法的基础上为每个文法符号(终结符或非终结符)配备若干个相关的“值”(称为属性)。
     属性:代表与文法符号相关的信息,和变量一样,可以进行计算和传递。可分为两类:
      综合属性
     继承属性(用于“自上而下”传递信息。在语法树中,一个结点的继承属性由此结点的父结点和/或兄弟结点的某些属性确定)
2、语义规则 
 属性计算的过程即是语义处理的过程, 对于文法的每一个产生式配备一组属性的计算规则,则称为语义规则。
    在一个属性文法中,对应于每个产生式A都有一套与之相关联的语义规则,每条语义规则的形式为:
     b:=f(c1,c2,…,ck) 
   这里f是一个函数,而且或者
   (1)b是A的一个综合属性并且c1,c2,…ck是产生式右边文法符号的属性;或者
   (2)b是产生式右边某个文法符号的一个继承属性并且c1,c2,…ck是A或产生式右边任何文法符号的属性
 在这两种情况下,我们都说属性b依赖于属性c1,c2,…,ck.
注意:
 (1)终结符只有综合属性,它由词法分析器提供
 (2)非终结符既可以有综合属性也可以有继承属性,文法开始符号的所有继承属性作为属性计算前的初始值。
 (3) 产生式右边符号的继承属性和产生式左边符号的综合属性都必须提供一个计算规则
 (4) 产生式左边符号的继承属性和产生式右边符号的综合属性不由所给的产生式的属性计算规则进行计算,它们由其它产生式的属性规则计算

3、描述类型信息提取的属性文法

4、语法制导翻译法的过程:输入串-->语法树-->依赖图-->语义规则计算次序-->计算结果
属性的计算次序
    一个有向非循环图的拓扑序是图中结点的任何顺序m1,m2, …mk,使得边必须是从序列中前面的结点指向后面的结点。也就是说,如果mi-->mj是mi到mj的一条边,那么在序列中mi必须出现在mj之前。    
 一个依赖图的任何拓扑排序都给出一个语法树中结点的语义规则计算的有效顺序。这就是说,在拓扑排序中,在一个结点上,语义规则b:=f(c1,c2,…ck)中的属性c1,c2…ck在计算b以前都是可用的。
树遍历的属性计算方法最常用的遍历方法是深度优先,从左到右的遍历方法, 如果需要,可使用多次遍历。

5、一遍扫描的处理方法是在语法分析的同时计算属性值,而不是语法分析构造语法树之后进行属性的计算,而且无需构造实际的语法树。 因为一遍扫描的处理方法与语法分析器的相互作用,它与下面两个因素密切相关:所采用的语法分析方法、属性的计算次序。

6. S-属性文法的自下而上计算
S—属性文法,它只含有综合属性。
综合属性可以在分析符号串的同时由自上而下的分析器来构造
分析器可以保存与栈中文法符号有关的综合属性值
每当进行归约时,新的属性值就由栈中正在归约的产生式右边符号的属性值来计算
可以通过扩充分析器中的栈来存放这些综合属性值
S-属性文法的翻译器通常可借助于LR分析器实现

 7、翻译模式的定义:
翻译模式是语法制导定义的一种便于翻译的书写形式。其中属性与文法符号相对应,语义规则或语义动作用花括号{ }括起来,可被插入到产生式右部的任何合适的位置上。
这是一种语法分析和语义动作交错的表示法,他表达在按深度优先遍历分析树的过程中何时执行语义动作。
翻译模式给出了使用语义规则进行计算的顺序。可看成是分析过程中翻译的注释。

8、设计翻译模式(根据语法制导定义)

语法制导定义是L-属性定义
保证语义动作不会引用还没有计算的属性值。
(1)只需要综合属性的情况
    为每一个语义规则建立一个包含赋值的动作,并把这个动作放在相应的产生式右边的末尾。
(2)既有综合属性又有继承属性
①产生式右边的符号的继承属性必须在这个符号以前的动作中计算出来。
②一个动作不能引用这个动作右边符号的综合属性。
③产生式左边非终结符号的综合属性只有在它所引用的所有属性都计算出来以后才能计算。计算这种属性的动作通常可放在产生式右端的未尾。
9、用翻译模式构造自顶向下翻译。
1)从翻译模式中消除左递归 
对于一个翻译模式,若采用自顶向下分析,必须消除左递归和提取左公因子,在改写基本文法时考虑属性值的计算。
2)关于左递归翻译模式更一般化的讨论
左递归翻译模式
         A→A1Y{A.a:=g(A1.a,Y.y)}
         A→X {A.a:=f(X.x)}                  (1式)
每一个文法符号都有一个综合属性,用相应的小写字母表示,g和f是任意函数。
消除左递归,文法转换成
         A→X R
         R→Y R|ε                              
再考虑语义动作,翻译模式变为:
         A→X {Ri:=f(X  x)}
                R    {A.  a:=R.  s}
         R→Y {R1  i:=g(R  i,Y  y)}
               R1   {R  s:=R1  s}
         R→ε{R  s:=R  i}  
10、语义分析的范围
1.确定类型:确定标识符所关联的数据类型。
2.类型检查:按语言的类型规则,检查运算的合法性与运算分量类型的一致性,必要时作类型转换。
3.识别含义:根据语言的语义定义(形式或非形式),识别程序中各构造成分组合到一起的含义,并作相应的语义处理(生成中间代码或目标代码)。
4.控制流检查:控制流语句必须转移到合法的地方。如C中,break语句规定跳出最内层的循环或switch语句。
5.一致性检查:在很多场合要求对象只能被说明一次。如:pascal语言规定同一个标识符在一个分程序中只能被说明一次等。
6.相关名字检查:如:Ada,循环或块可以有一个名字,它出现在这些结构的开头或结尾。编译程序必须检查这两个地方用的名字是否相同。
其它:如名字的作用域分析等也是语义分析的工作。
11、语义描述工具和语义分析方法
语义描述工具
   目前流行:用属性文法作为描述语义的工具。
语义分析方法
 根据描述属性文法的语义规则的方式不同分为:语法制导定义、翻译方案
12、语法制导翻译:对文法中的每个产生式都附加上一个语义动作或语义子程序。伴随着语法分析,每当使用一条产生式进行推导或归约时,就执行相应产生式的语义动作(包括:查填表格,改变变量的求值,诊察与报告错误,生成中间代码等),从而完成预定的翻译工作。
自底向上的语法制导翻译
自顶向下的语法制导翻译
13.几种常用的中间语言形式
1)逆波兰式即后缀表达式       例:    a*(b+c) → abc+*
2)图示法-----抽象语法树(无循环有向图)
3)三元式(算符:OP, 第一运算分量:ARG1, 第二运算分量:ARG2)
    间接三元式:在三元式的基础上附加一张指示器表─间接码表,按运算的先后顺序列出有关三元式在三元式表中的位置。
4)四元式(算符:OP, 第一运算分量:ARG1, 第二运算分量:ARG2,运算结果:result)
14、赋值语句的翻译
  1)简单算术表达式的赋值语句:
      所谓简单指不考虑数组元素、记录、函数的引用等情况。
例:S→id:=E  
  E→E1+E2∣E1*E2∣(E1)∣-E1∣id
S→id:=E     {p:=lookup(id.name);
                if (p!=nil) then
          emit(p‘:=’E.place)
                else error}
  E→E1 op E2  {E.place:= newtemp;
                emit(E.place‘:=’ E1.place opE2.place)}
  E→-E1       {E.place:=newtemp;
                emit(E.place‘:=’‘uminus’ E1.place)}
  E→(E1)      {E.place:= E1.place}
  E→id        {p:=lookup(id.name);
          if (p!=nil) then  E.place:=p
                   else  error}
2)类型转换
  我们可以把类型信息反映到运算符中,例如用+i,*i表示定点+、*,用+r,*r表示浮点+、*。有的程序设计语言允许混合运算,有的不允许。如果不允许,则发现有类型不相同的运算分量就应该报错。如果允许,就要进行类型转换。
     按照惯例,整、实运算要全部转成实型。处理的方法就是:给每个非终结符添加一个类型信息,如我们用E.MODE表示E的类型,其值为r或者i。
  如此一来,关于E→E1 op E2 的语义子程序也应作相应改动,使其在必要时能产生对运算分量进行类型转换的四元式。
15、数组元素的地址计算公式
一维数组:假定数组的每个元素的宽度为w,则一维数组A[i] 这个元素的起始地址为:
                            base + (i – low)*w
            其中,low为数组下标的下界, base是分配给数组的相对地址,即base为A的第一个元素A[low]的相对地址。
二维数组:若二维数组A按行存放,则可用如下公式计算A[i1,i2]的相对地址:
    base + (( i1 – l1)*d2 + i2 – l2) *w
    其中,l1、l2分别为i1、i2的下界;di界差。若ui为i的上界,则di=ui – li +1.
数组的翻译方案是:
      产生两组计算数组元素地址的四元式:
      一组是计算VARPART,并将计算结果放入临时变量T1,
      另一组是计算CONSPART,并将计算结果放入临时变量T2,同时用T2[T1]表示数组元素的地址。
16、控制流语句的翻译
if条件语句中布尔表达式的翻译
  出现在条件语句if E then S1 else S2中的布尔表达式E,它的作用仅在于控制对S1或S2的选择,亦即提供“真”“假”出口,所以其值无需一直保留。可以把作为控制条件的任何布尔表达式表示成仅含下列三种形式的四元式的序列:
   (jnz,a,--,p)  表示 if  a goto  p
   (jrop,x,y,p)  表示 if  x rop y  goto p
   (j,--,--,p)   表示 goto  p

17、 过程调用主要解决两个问题:
      (1)把程序控制转移到子程序(过程段),执行完毕再返回。这个问题很好解决。
      (2)传递实在参数。我们前面谈到过几种不同的参数传递方式(传名、传值、传地址),它们的语义动作也就有所区别。
总结:六七章比较来说,我觉得第六章有点抽象,第七章就很好理解,从逆波兰式,到三元四元式,再到布尔表达式的翻译,感觉只要思路清晰就没多大问题,我觉得自己重实践轻理论,所以这几张总结的差不多都是知识点。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值