语义分析包括确定类型,类型检查,识别含义,控制流检查,一致性检查和相关名字检查以及其他功能。他的任务是检查语法的正确结构是否有意义并在语义正确的基础上生成一种中间代码和目标代码。其中语法的制导翻译包括自底向上的语法制导翻译和自顶向下的语法制导翻译。而他生成的中间语言形式包括1.波兰表示(前缀式,运算符在前)和逆波兰表示(后缀式,运算符在后),2.图表示法即抽象语法树形式其结构使中序遍历时为正常的运算式,前序遍历时为波兰表示,后序遍历时为逆波兰表示。 

3.三元式()对于一目运算符,我们可以规定只用ARG1,而多目运算符可以用若干条相继的三元式来表示。) 3.1间接三元式()在三元式的基础上附加一张指示器表─间接码表,按运算的先后顺序列出有关三元式在三元式表中的位置。这种表示方法称为间接三元式)。4.四元式(比三元式加了一个RESULT Ti其中Ti是临时变量)

 树的表示中  产生式            语义动作

  (1)E→E1 op E2  {E.val:=NODE(op,E1.val,E2.val)}其中NODE是建立一棵新树,以OP为根,以E1.val,E2.val为左右枝。返回指向树根的指针
  (2)E→(E1)      {E.val:=E1.val}
  (3)E→-E1       {E.val:=UNARY(@E1.val)}UNARY与NODE相似,只不过是单枝。

  (4)E→i         {E.val:=LEAF(i)} LEAF建立以i.LEXCAL为标志的叶结,回送的是结点i的地址。

3. 三元式

对于一目运算符,我们可以规定只用ARG1,而多目运算符可以用若干条相继的三元式来表示。
                  OP    ARG1    ARG2
  例2:-x+y*z   (1) @     x       --
                       (2) *     y       z

                       (3) +    (1)     (2)

其中@为负号,并且表示-x时ARG无值,并且应当注意运算的先后顺序。这也增加了计算机在计算时的难度由于三元式的计算过程跟先后顺序密切相关,这就给优化带来麻烦,所以一般不直接使用三元式

  例3:赋值语句的三元式表示        
                    OP    ARG1    ARG2
    A:=x+y*z    (1) *     y       z
                (2) +     x      (1)

                (3) :=    A      (2)

本例中加入了赋值语句

由树的表示法转化为三元表的语句为

{E.val:=TRIP(OP,E1.val,E2.val)}

      这儿TRIP(OP,ARG1,ARG2)是一个语义过程,它产生(OP,ARG1,ARG2)并放入三元式表中,返回三元式在表中的位置。

3.1间接三元式

在三元式的基础上附加一张指示器表─间接码表,按运算的先后顺序列出有关三元式在三元式表中的位置。这种表示方法称为间接三元式。

我们学习过儿的中间语言有汇编语言,三地址语句的种类(1)赋值语句 x:=y op z,op为二目算术算符或逻辑算符;(2)赋值语句 x:=op y ,op为一目算符,如一目减uminus、逻辑非not、移位算符及转换算符;(3)无条件转移语句goto L;(4)条件转移语句 if x relop y goto L,关系运算符号relop(< ,=,>= 等等);(5)复制语句  x:=y;(6)过程调用语句 param x 和 call p, n ;过程返回语句 return y;(7)索引赋值 x:=y[i] 及 x[i] :=y ;(8)地址和指针赋值 x=&y,x=* y和  * x=y。语法制导翻译生成三地址代码  (1)E.place表示存放E值的名字。(2)E.code表示对E求值的三地址语句序列。(3)   newtemp是个函数,对它的调用将产生   一个新的临时变量。三地址代码的具体实现1.四元式  op, arg1, arg2, result 2.三元式 op, arg1, arg2
3.间接三元式  间接码表+三元式表,数组地址计算:常量部分+变量部分:bace-low*w +  i*w     A[i1,i2] 的地址:base+((i1 一low1)* n2+i2 一low2)*w)= base-((low1 *n2)+low2)*w + ((i1*n2)+i2)* w  用数组来表示 L→Elist]| id    Elist→Elist,E|id[ E   地址计算变量部分:   ((i1*n2+i2)*n3+i3)*n4+。。。   可利用递归公式计算: e1= i 1, 

e2=e1*n2+i2;e3=e2*n3+i3…em=em-1*nm+im;其中 有关变量与函数的说明Elist.ndim:记录Elist中的下标表达式的 个数,即维数。Elist.place:临时变量,用来临时存放由Elist  中的下标表达式计算出来的值;   Elist 引进综合属性array,指向数组名a在符号表中的入口地址.L有两个属性值: L.Place和L.offset。L.Place:如果L为一个简单名字,则L.Place为指向该名字在符号表中的入口的指针;如果L不为一个简单名字,则L.Place为数组计算中的常数部分,base-c L.offset=null:表示L为一个简单名字

L.offset不为空,表示数组元素引用

布尔表达式 

布尔表达式:a or b and not c 


 翻译成三地址代码序列:
    100 : t1:=not c 
    101 : t2:=b and t1

    102 : t3:=a or t1 

翻译成三地址代码序列:

100 : if a<b goto l03 
101 : t:=0 
102 : goto l04。 
103 :    t:=1 

104:

四元式序列:

100:(j<,a,b,103)
101: (= ,0,  ,t) 
102:(j  ,  ,  ,104)
103 : (= ,1,  ,t) 

104:



第七章 语义分析和中间代码的产生

第七章 语义分析和中间代码的产生第七章 语义分析和中间代码的产生第七章 语义分析和中间代码的产生

总结:本章需要练习的东西比较多,尤其是四项式与C语言的转化,以及表达式与三项式的及间接三项式的转化。

相关文章: