编译原理第六章属性文法和语法制导翻译.docx

上传人:b****4 文档编号:4024244 上传时间:2022-11-27 格式:DOCX 页数:25 大小:278.10KB
下载 相关 举报
编译原理第六章属性文法和语法制导翻译.docx_第1页
第1页 / 共25页
编译原理第六章属性文法和语法制导翻译.docx_第2页
第2页 / 共25页
编译原理第六章属性文法和语法制导翻译.docx_第3页
第3页 / 共25页
编译原理第六章属性文法和语法制导翻译.docx_第4页
第4页 / 共25页
编译原理第六章属性文法和语法制导翻译.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

编译原理第六章属性文法和语法制导翻译.docx

《编译原理第六章属性文法和语法制导翻译.docx》由会员分享,可在线阅读,更多相关《编译原理第六章属性文法和语法制导翻译.docx(25页珍藏版)》请在冰豆网上搜索。

编译原理第六章属性文法和语法制导翻译.docx

编译原理第六章属性文法和语法制导翻译

第六章属性文法和语法制导翻译

要紧内容:

[1]法制导翻译的大体思想;

[2]属性文法的大体概念;

[3]基于属性文法的处置方式;

[4]在自上而下分析和自下而上分析中的属性计算。

大体要求:

[1]明白得语法制导翻译和属性文法的大体思想和方式,

[2]把握属性的计算方式。

教学要点:

本章中,咱们将第一介绍属性文法的大体概念,然后介绍基于属性文法的处置方式,讨论如安在自上而下分析和自下而上分析中实现属性的计算。

讲义摘要:

6.1属性文法

一、语义分析的任务

一、静态语义分析或静态审查。

        

例如,类型检查、操纵流检查(操纵流语句必需使操纵转移到合法的地址)、维数检查、越界检查、名字的作用域分析等。

二、动态语义处置。

       

 若是静态语义正确,语义处置那么要执行真正的翻译。

例如,变量的存储分派;表达式的求值;语句的翻译(中间代码的生成)。

3、总目标:

生成等价的中间代码

语法分析

后的源程序

语义处理

中间代码

二、属性文法

一、属性

所谓属性,其涉及的概念比较普遍,经常使用以描述事物或人的特点、性质,品质等等。

比如,谈到一个物体,能够用“颜色”描述它,谈起某人,能够利用“有幽默感“来形容他。

对编译程序利用的语法树的结点,能够用"类型"、"值"或"存储位置"来描述它。

二、属性文法(也称属性翻译文法)

属性文法是Knuth在1968年第一提出的。

它是在上下文无关文法的基础上,为每一个文法符号(终结符或非终结符)配备假设干相关的“值”(称为属性)。

这些属性代表与文法符号相关信息,例如它的类型、值、代码序列、符号表内容等等。

属性与变量一样,能够进行计算和传递。

属性加工的进程即是语义处置的进程。

关于文法的每一个产生式都配备了一组属性的计算规那么,称为语义规那么。

语义规那么所描述的工作能够包括属性计算、静态语义检查、符号表操作、代码生成等等。

 3、属性文法的形式化概念

   形式上讲,一个属性文法是一个三元组:

A=(G,V,F),其中    G:

是一个上下文无关文法。

    V:

有穷的属性集,每一个属性与文法的一个终结符或非终结符相连。

    F:

关于属性的属性断言或谓词集。

每一个断言与一个产生式相联。

一个断言确实是一个语义规那么,描述各属性的关系。

(谓词表示个体的一种属性。

例如用P(x)表示x是一棵树,那么P(y)表示y是一棵树,用Q(x)表示x有叶,那么Q(y)表示y也有叶。

那个地址P、Q是一元谓词,x,y是个体,公式"x(P(x)→Q(x))表示每一棵树都有叶子,那个地址"是全称量词表示“每一个”。

用法:

针对语义:

为每一个符号设置一个属性,终结符号用单词属性。

为每一个产生式设置语义规那么——描述各属性的关系。

例如:

概念表达式的文法如下:

E→E+EE→(E)E→n给出概念表达式值的属性文法。

解:

咱们为文法符号E引进属性符号val,用E.val表示E的值,属性计算规那么以赋值语句的形式给出,附在每一个产生式后,并用大括号括起来。

为了明确E的不同显现位置,用上角标区别。

终结符n的值是词法分析程序提供的,那个地址用n.lex表示。

下面给出属性文法:

E→E1+E2{E.val:

=E1.val+E2.val}

E→(E1){E.val:

=E1.val}

E→n{E.val:

=n.lex}

总结:

 属性文法的要紧思想有两点:

第一关于每一个文法符号引进相关的属性符号;第二关于每一个产生式写出属性值计算的规那么。

4、属性的分类

属性通常分为两类:

综合属性和继承属性。

简单地说,综合属性用于“自下而上”传递信息,而继承属性用于“自上而下”传递信息。

(a)综合属性:

在语法树中,一个结点的综合属性的值由其子结点的属性值确信;利用自底向上的方式在每一个结点处利用语义规那么计算综合属性的值;仅仅利用综合属性的属性文法称S-属性文法。

例题1:

    例如:

概念表达式值的属性文法,E.val是一个综合属性的例子:

              E->E1+E2  {E.val:

=E1.val+E2.val}

              E->(E1)  {E.val:

=E1.val}

              E->n  {E.val:

=n.lex}

     考虑句子2+(3+1)的求值顺序,将2+(3+1)的语法树结点改成有附加属性的结点(如此的树称为带注释的语法树):

E.val=6

例题2:

一个简单台式计算器的概念综合属性val

产生式语义规则

L→Enprint(E.val)

E→E1+TE.val:

=E1.val+T.val

E→TE.val:

=T.val

T→T1*FT.val:

=T1.val*F.val

T→FT.val:

=F.val

F→(E)F.val:

=E.val

F→digit

输入3*5+4n求其带注释的语法树。

digit⋅lexval:

=3

F⋅val:

=3

T⋅val:

=3

digit⋅lexval:

=5

F⋅val:

=5

T⋅val:

=15

*

E⋅val:

=15

+

digit⋅lexval:

=4

F⋅val:

=4

T⋅val:

=4

E⋅val:

=19

L

n

(b)继承属性

在语法树中,一个结点的继承属性由此结点的父结点和/或兄弟结点的某些属性确信;用继承属性来表示程序设计语言结构中的上下文依托关系很方便。

例1描述说明语句中各类变量的类型信息的语义规那么,那个例子里,继承属性在说明中为各个标识符提供类型信息。

  产生式      语义规那么∶=T.type}∶=integer}∶=real}∶            addtype(id.entry,L.in)}  (5)L→id    {addtype(id.entry,L.in)}

分析:

例1∶=T.type将L.in的属性值置为该说明语句指定的类型。

属性L.in将被沿着语法树传递到下边的结点利用,与L产生式相联的规那么里利用了它。

 下图是句子intid1,id2的语法树,利用

表示属性的传递情形。

在语法树中,一个结点的继承属性由此结点的父结点和/或兄弟结点的某些属性确信。

与L产生式相联的语义规那么中有一个进程挪用addtype,进程addtype的功能是把每一个标识符的类型信息登录在符号表的相关项中。

图属性信息传递情形

属性文法看做是许诺为每一个终结符和非终结符配备一些属性的文法。

它既能描述程序设计语言的语法,又为语义处置提供了方便.属性文法里的属性有不同的类型,能够象变量一样地被赋值。

赋值规那么附加于语法规那么之上。

赋值与语法同时进行,赋值进程确实是语义处置进程。

在推导语法树的时候,诸属性的值被计算并通过赋值规那么层层传递。

有的从语法规那么左侧向右边传,有的从右边向左侧传。

语法推导树最后完成时,就取得开始符号的属性值。

也确实是整个程序的语义。

 例2,上例文法中,求句子realid1,id2,id3的带注释的语法树,并说明其属性的传递情形。

id1

L

id2

L

id3

L

real

T

D

T.type=real

L.in=real

L.in=real

L.in=real

五、属性文法举例

  咱们不对属性文法进行理论上的研究而仅仅将它做为工具描述语义分析。

在编译的许多实际应用中,属性和断言以多种形式显现,也确实是说,与每一个文法符号相联的能够是各类属性、断言、和语义规那么,或某种程序设计语言的程序段等等。

一样说来,对出此刻产生式右边的继承属性和出此刻产生式左侧的综合属性都必需提供一个计算规那么。

属性计算规那么中只能利用相应产生式中的文法符号的属性,这有助于在产生式范围内"封装"属性的依托性。

但是,出此刻产生式左侧的继承属性和出此刻产生式右边的综合属性不由所给的产生式的属性计算规那么进行计算,它们由其它产生式的属性规那么计算或由属性计算器的参数提供。

  语义规那么所描述的工作能够包括属性计算、静态语义检查、符号表操作、代码生成等等。

语义规那么可能产生副作用(如产生代码),也可能不是变元的严格函数(如某个规那么给出可用的下一个数据单元的地址)。

如此的语义规那么通常写成进程挪用或进程段。

下面再给出一些例子。

 在该描述中,每一个非终结符都有一个属性:

一个整数值的称作val的属性。

依照语义规那么对每一个产生式来讲,它的左部E,T,F的属性值的计算来自它右部的非终结符,这种属性称作综合属性。

单词digit仅有综合属性,它的值是由词法分析程序提供的。

和产生式L→E相联的语义规那么是一个进程,打印由E产生的表达式的值。

咱们能够明白得为L的属性是空的或是虚的。

 

 例1.用属性文法表示简单的无符号数文法:

    number→numberdigit|digit    digit→0|1|2|3|4|5|6|7|8|9    [分析]一个数最重要的属性是它的值,咱们将其命名为val。

每一个数字都有一个值,能够用它表示的实际数直接计算。

因此,文法规那么digit→0说明digit的值为0。

也能够用属性等式digit.val=0表示,咱们将那个等式和规那么digit→0联系在一路。

若是一个数利用了下面的规那么推导number→digit,那么那个数就只包括了一个数字,其值确实是那个数字的值。

用属性等式表示为al    若是一个数包括的数字多于1个,能够利用以下文法规那么推导    number→numberdigit    咱们必需表示出那个文法规那么左侧符号的值和右边符号的值之间的关系。

通过利用下标进行区分,将文法写成如下形式:

    number1→number2digit    此刻考虑一个数如34。

那个数的(最左)推导如下:

    number=>numberdigit=>digitdigit=>3digit=>34    相应的属性等式是    number1.val=number2.val*10+digit.val    完整的val属性文法为:

    文法规那么语义规那么    number1→number2digitnumber1.val=number2.val*10+digit.val    Number→digitnumber.val=digit.val    digit→0digit.val=0    digit→1digit.val=1    digit→2digit.val=2    digit→3digit.val=3    digit→4digit.val=4    digit→5digit.val=5    digit→6digit.val=6    digit→7digit.val=7    digit→8digit.val=8    digit→9digit.val=9

    利用语法树能够形象化地表示特殊字符串的属性等式的意义。

    例2考虑以下简单的整数算术表达式文法:

    exp→exp+term|exp-term|term    term→term*factor|factor    factor→(exp)|number

    文法规那么语义规那么    exp1→exp2+termexp1.val=exp2.val+term.val    exp1→exp2-termexp1.val=exp2.val-term.val    exp→termexp.val=term.val    term1→term2*factorterm1.val=term2.val*factor.val    term→factorterm.val=factor.val

    这些等式表示了表达式的语法和它所进行的算术运算的语义之间的关系。

注意,在文法规那么exp1→exp2+term中语义符号+(记号)和等式exp1.val=exp2.val+term.val中执行的算术加运算符+的不同。

还要注意number.val可不能在等式的左侧。

因为必需在任意一个利用那个属性文法的语义分析之前计算number.val。

    一样也能够通过在语法树的节点上附加等式来表示属性文法包括的计算。

例3:

已知表达式文法E—>T+T|TorT    T—>n|b    求对应的属性文法。

    E→T1+T2    {T1.type=int

    T2.type=T1.type    E.type:

=int}    E→T1orT2    {T1.type=bool        E.type:

=bool}    T→n    {T.type:

=int}    T→b    {T.type:

=bool}

6.2语法制导翻译概述

一、语法制导翻译(Syntax-directeddefinitions)

一、概念

由源程序的语法结构所驱动的处置方法确实是语法制导翻译法。

二、大体思想

语法制导翻译(Syntax-directeddefinitions)的大体思想是,依照翻译的需要设置文法符号的属性,以描述语义。

(例如,一个变量的属性有类型,层次,存储地址等。

表达式的属性有类型,值等。

属性值的计算和产生式相联系。

)在语法分析进程中,随着语法分析的进行,随着分析的步步进展,依照每一个产生式所对应的语义子程序(或语义规那么描述的语义动作),执行属性值的计算,完成语义分析和翻译的任务。

3、语法制导翻译的流程

 

语法

实际上,编译中语义翻译的实现并不是按图中的流程处理的;而是随语法分析的进展,识别出一个语法结构,就对它的语义进行分析和翻译。

说明:

语义翻译进程如图。

随语法分析的进展,每识别出一个语法结构,就对它的语义进行分析和翻译。

一个语法制导翻译的基础是一个文法,其翻译依托于每一个产生式。

语义规那么的计算可能产生代码、在符号表中寄存信息、给犯错误信息或执行任何其它动作。

对输入符号串的翻译也确实是依照语义规那么进行计算的结果。

但是,一个具体的实现并非必然非要按上图的轮廓不可。

在某些情形下可用一遍扫描实现属性文法的语义规那么计算。

也确实是说在语法分析的同时完成语义规那么的计算,那么计算顺序由分析方式来确信而表面上与语义规那么无关,或在构造编译器时,用手工或专门的工具来分析语义规那么,确信属性值的计算顺序。

没必要显式构造语法树或构造属性之间的依托图,因现在空效率更高。

编译程序的整个任务确实是把源程序翻译为目标程序。

事实上每一个编译时期都能够看成是完成必然的翻译任务:

词法分析时期把字符流翻译为单词流,语法分析时期把单词流翻译为语法树,目标代码生成时期把语法树翻译为汇编语言等等。

二、依托图

在一棵语法树中的结点的继承属性和综合属性之间的彼此依托关系能够由称作依托图的一个有向图来描述

在一个属性文法中,对应于每一个产生式A→a都有一套与之相关联的语义规那么,如此把每一个语义规那么都写成

  b:

=f(c1,c2,…ck)的形式  那个地址,f是一个函数,而且或  

(1)b是A的一个综合属性而且c1,c2,…ck是产生式右边文法符号的属性:

或  

(2)b是产生式右边某个文法符号的一个继承属性而且c1,c2,…ck是A或产生式右边任何文法符号的属性。

  在两种情形下,咱们都说属性b依托于属性c1,c2,…ck。

依托图中为每一个属性设置一个结点,若是属性b依托于属性c,那么从属性c的结点有一条有向边连到属性b的结点。

依托图的构造方式:

for语法树中每一结点ndo

for结点n的文法符号的每一个属性ado

为a在依托图中成立一个结点;

for语法树中每一个结点ndo

for结点n所用产生式对应的每一个语义规那么

b:

=f(c1,c2,…,ck)do

fori:

=1tokdo

从ci结点到b结点构造一条有向边;

例1:

文法和语义规那么如下:

E→E1+E2E.val:

=E1.val+E2.val

+

E2

E

val

val

val

有向图为依赖图,虚线为语法树,它不是依赖图中的一部分。

E1

    [分析]那个地址只有一个属性val,因此每一个符号在每一个依托图中只有一个节点对应于其val属性。

Val为综合属性。

例2:

句子realid1,id2,id3的带注释的语法树的依托图

 

id1

L

id2

L

id3

L

real

T

D

4

type

5

Int

6-addtype(id.entry,L.in)

7

Int

8addtype

9

Int

10addtype

1

entry

2

entry

3

entry

三、属性的计算顺序

一个依托图的任何拓扑排序(TopologicalSort)都给出一个语法树中结点的语义规那么计算的有效顺序

众所周知,存在拓扑排序的充分必要条件是相关图必需是非循环的,如此的图形称作有向非循环图(DirectedAcyclicGraphs,DAGs)。

   一个有向非循环图的拓扑排序是图中结点的任何顺序m1,m2,…,mk,使得边必需是从序列中前面的结点指向后面的结点,也确实是说,若是mi→mj是mi到mj的一条边,那么在序列中mi必需出此刻mj的前面。

假设依托图中无环,那么存在一个拓扑排序,它确实是属性值的计算顺序。

   咱们看到编译时相关图的构造是基于特定的语法树的,那个方式称作语法分析树方式(ParseTreeMethod)

四、属性文法的处置方式

基于属性文法的处置方式通常有两类:

树遍历的属性计算方式;一遍扫描的处置方式。

1.树遍历的属性计算方式

通过树遍历计算属性值的方式有多种。

这些方式都假设语法树已经成立起了,而且树中已带有开始符号的继承属性和终结符的综合属性。

然后以某种顺序遍历语法树,直至计算出所有属性。

最经常使用的遍历方式是深度优先,从左到右的遍历方式。

若是需要的话,可利用多次遍历(或称遍)。

下面的遍历算法可对任何无循环的属性文法进行计算:

While还有未被计算的属性do

VisitNode(S)/*S是开始符号*/

procedureVisitNode(N:

Node);

begin

ifN是一个非终结符then

/*假设它的产生式为N→X1…Xm*/

fori:

=1tomdo

ifXi∈VNthen/*即Xi是非终结符*/

begin

计算Xi的所有能够计算的继承属性;

VisitNode(Xi)

end;

计算N的所有能够计算的综合属性

end

只要文法的属性是非循环概念的,那么每一次扫描至少有一个属性值被计算出来。

若是语法树有n个结点(因此最多有O(n)个属性),最坏的情形整个遍历需O(n²)时刻。

例:

考虑属性的文法G。

其中,S有继承属性a,综合属性b;X有继承属性c、综合属性d;Y有继承属性e、综合属性f;Z有继承属性h、综合属性g。

(依照概念)

产生式语义规那么

S→XYZ

S.b:

=X.d-2

X→

Y→yY.f:

=Y.e*3

Z→zZ.g:

=Z.h+1

假设S.a的初始值为0,输入串为xyz

第一次遍历的执行进程如下:

VisitNode(S)

VisitNode(X)

Y.e不能计算

VisitNode(Y)

Z.h:

=0

VisitNode(Z)

Z.g:

=1

S.b不能计算

二、一遍扫描的处置方式

与树遍历的属性计算方式不同,一遍扫描的处置方式是在语法分析的同时计算属性值,而不是语法分析构造语法树以后进行属性的计算,而且无需构造实际的语法树。

因为一遍扫描的处置方式与语法分析器的彼此作用,它与下面两个因素紧密相关:

(1).所采纳的语法分析方式。

(2).属性的计算顺序。

若是按这种一遍扫描的编译程序模型来明白得语法制导翻译方式的话,所谓语法制导翻译法,直观上说确实是为文法中每一个产生式配上一组语义规那么,而且在语法分析的同时执行这些语义规那么。

在自上而下语法分析中,假设一个产生式匹配输入串成功,或,在自下而上分析中,当一个产生式被用于进行归约时,此产生式相应的语义规那么就被计算,完成有关的语义分析和代码产生的工作。

可见,在这种情形下,语法分析工作和语义规那么的计算是穿插进行的。

五、抽象语法树(SyntaxTree)的构造

   

(1)抽象语法(AbstractSyntax)

   抽象语法的目的是不考虑语言的具体符号表示,从具体语法中抽象出语言结构的本质性东西,从而简化语义的形式描述。

   例如:

在不同的语言中赋值语句有不同的写法:

x=y;x:

=y;y→x等等,能够用抽象形式assignment(variable,expression)把前面各类具体形式统一路来。

   

(2)抽象语法树

   语法树是经常使用的一种中间表示形式。

在语法树中去掉那些对语义无关紧要的成份,从而取得更有效的源程序中间表示,是语法树的抽象形式。

这种经变换后的语法树称之为抽象语法树(AbstractSyntaxTree)。

   例1:

产生式S→ifBthenS1elseS2的抽象语法树。

(如以下图)

   if-then-else   /|\   BS1S2

例2:

赋值语句的抽象语法树。

(如以下图)

   assignment      /     \   variableexpression

   在抽象语法树中,运算符号和关键字都不作为叶结点显现,而是把它们作为内部结点。

即这些叶结点的父结点。

例3:

3*5+4的语法树。

(如以下图)

+      /     \   *4

  /     \  35

   (3)成立表达式的抽象语法树

   下面讨论如何成立表达式的抽象语法树。

成立表达式的抽象语法树与把表达式翻译成后缀形式类似。

咱们通过为每一个运算分量或运算符号都成立一个结点来为子表达式成立子树。

运算符号结点的各子结点别离是表示该运算符号的各个运算分量的子

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1