语言的语法及其翻译方案

2019-04-09 17:27

各种语言成分的语法及其翻译方案(示例)

1. 普通声明语句的翻译

下面是声明语句的文法:

P → prog id (input, output) D ; S D →D ; D | List : T | proc id D ; S List →List1, id | id

T → integer | real | array C of T1 | ?T1 | record D C → [num] C | ε

声明语句的翻译模式:

P→prog id (input, output){offset := 0}D ; S D→D ; D

D→id: T{enter (id.name, T.type, offset); offset:= offset + T.width} T→integer{T.type := integer; T.width := 4} T→real{T.type :=real; T.width :=8}

T→array [num] of T1{T.type := array(num.val, T1.type);T.width := num.val×T1.width} T→↑T1{T.type := pointer(T1.type); T.width := 4}

2. 嵌套过程中声明语句的翻译

嵌套过程声明语句的产生式。 P→prog id (input, output) D ; S D→D ; D | id : T | proc id ; D ; S (7.1) 嵌套过程声明语句的翻译模式:

P→prog id (input, output) MD;S{addwidth(top(tblptr),top(offset));

pop(tblptr);pop(offset)}

M→ε{t := mktable(nil);push(t, tblptr); push(0, offset)} D→D1;D2

D→proc id; N D1 ; S{t:= top(tblptr);addwidth(t, top(offset));pop(tblptr);

pop(offset); enterproc(top(tblptr), id.name,t)}

D →id : T{enter(top(tblptr), id.name, T.type, top(offset));

top(offset) := top(offset) + T.width}

N →ε{t:= mktable(top(tblptr)); push(t, tblptr); push(0, offset)}

3. 记录的翻译

下面是生成记录类型的产生式: T→record D end

生成记录类型的翻译模式:

T → record L D end {T.type := record(top(tblptr));

T.width := top(offset); pop(tblptr); pop(offset)}

L →ε{t:= mktable(nil); push(t, tblptr); push(0, offset)}

4. 赋值语句的翻译

下面是典型的赋值语句文法:

S →Left := E

E →E1 + E2 | E1 * E2 | - E1 | (E1 ) | Left Left →Elist ] | id Elist →Elist, E | id [E (7.2) 赋值语句的翻译模式:

⑴ S→Left:=E{if Left.offset=null then /*Left是简单变量id*/

gencode(Left.addr ':=' E.addr);

1

else

gencode(Left.addr '[' Left.offset '] ' ':=' E.addr)} /*Left是数组元素*/

⑵ E→E1+E2{E.addr:=newtemp;gencode(E.addr ':='E1.addr'+'E2.addr)} ⑶ E→(E1){E.addr:= E1.addr}

⑷ E→Left{if Left.offset=null then /*Left是简单id*/

E.addr:= Left.addr

else begin /*Left是数组元素*/

E.addr:=newtemp;

gencode(E.addr ':=' Left.addr ' [' Left.offset ']') end}

⑸ Left→Elist]{ Left.addr:=newtemp; /*Left是数组元素,因此存放基址和位移*/

Left.offset:=newtemp;

gencode(Left.addr ':=' c(Elist.array));

gencode(Left.offset ':=' Elist.addr '*' width(Elist.array))}

⑹ Left→id{Left.addr:=id.addr; Left.offset:=null} ⑺ Elist→Elist1, E{t:=newtemp;m:= Elist1.ndim+1;

gencode(t ':=' Elist1.addr '*' limit(Elist1.array, m)); /*计算em-1×nm */ gencode(t ':=' t '+' E.addr); /* 计算+ im */ Elist.array:= Elist1.array; Elist.addr:=t; Elist.ndim:=m}

⑻ Elist→id[E {Elist.array:=id.addr; Elist.addr:= E.addr; Elist.ndim:=1}

5.各种控制结构的翻译 5.1 布尔表达式的翻译

布尔表达式的文法为: ⑴ B→B1 or M B2 ⑵ B→B1 and M B2 ⑶ B→not B1 ⑷ B→(B1) ⑸ B→E1 relop E2 ⑹ B→true ⑺ B→false ⑻ M→ε

布尔表达式的翻译模式如下所示: ⑴B→B1 or M B2{ backpatch(B1.falselist, M.quad); B.truelist := merge(B1.truelist, B2.truelist); B.falselist := B2.falselist} ⑵B→B1 and M B2{backpatch(B1.truelist, M.quad); B.truelist := B2.truelist; B.falselist := merge(B1.falselist, B2.falselist)} ⑶B→not B1{B.truelist := B1.falselist; B.falselist := B1.truelist} ⑷B→(B1) {B.truelist := B1.truelist; B.falselist := B1.falselist} ⑸B→E1 relop E2{B.truelist :=makelist(nextquad); B.falselist := makelist(nextquad+1);

2

gencode('if' E1.addr relop.opE1.addr 'goto –'); gencode('goto –')} ⑹B→true{B.truelist := makelist(nextquad); gencode('goto –')} ⑺B→false{B.falselist := makelist(nextquad); gencode('goto –')} ⑻M→ε{M.quad := nextquad}

5.2 常用控制流语句的翻译

控制流语句if-then,if-then-else和while-do的文法为: ⑴S→if B then S1 ⑵S→if B then S1 else S2 ⑶S→while B do S1 ⑷S→begin L end ⑸S→A ⑹L→L1;S ⑺L→S (7.9) if-then,if-then-else和while-do语句的翻译模式: ⑴S→if B then M1 S1 N else M2 S2{backpatch(B.truelist, M1.quad);

backpatch(B.falselist, M2.quad);

S.nextlist := merge(S1.nextlist, merge(N.nextlist, S2.nextlist))}

⑵N→ε{N.nextlist := makelist(nextquad); gencode('goto –')} ⑶M→ε{M.quad := nextquad} ⑷S→if B then M S1{backpatch(B.truelist, M.quad); S.nextlist := merge(B.falselist, S1.nextlist)} ⑸S→while M1 B do M2 S1{backpatch(S1.nextlist, M1.quad);

backpatch(B.truelist,M2.quad);S.nextlist:=B.falselist; gencode('goto'M1.quad)} ⑹S→begin L end{S.nextlist:=L.nextlist} ⑺S→A{S.nextlist := nil} ⑻L→L1;MS{backpatch(L1.nextlist, M.quad); L.nextlist := S.nextlist} ⑼L→S{L.nextlist := S.nextlist}

5.3 for循环语句的翻译

for循环语句的文法如下所示:

S → for id := E1 to E2 step E3 do S1

for循环语句的翻译模式如下所示:

S → for id := E1 to E2 step E3 do M S1 {backpatch(S1.nextlist, M.again,);

gencode(‘goto’, -, -, M.again); S.nextlist := M.again;}

M→ε {M.addr := entry(id); gencode(‘:=’, E1.addr, -, M.addr); T1:=newtemp;

gencode(‘:=’, E2.addr, -, T1); T2:=newtemp; gencode(‘:=’, E3.addr, -, T2); q:=nextquad; gencode(‘goto’, -, -, q+2); M.again:=q+1; gencode(‘+’, M.addr, T2, M.addr); M.nextlist:=nextquad; gencode(‘if’ M.addr ‘>’T1‘goto –’);}

5.4 repeat语句的翻译

repeat语句的文法如下所示:

S→ repeat S1 until B

Repeat语句的翻译模式如下所示:

S→repeat M S1until N B{backpatch(B.falselist,M.quad);

S.nextlist:=B.truelist}

3

M→ε{M.quad := nextquad}

N→ε{backpatch(S1.nextlist, nextquad)}

6. switch语句的语法制导翻译

switch语句的文法为: S → switch (E ) Clist Clist→ case V : S Clist | default : S

switch语句的翻译模式如下所示:

⑴S→switch (E){i:=0; Si.nextlist:=0; push Si.nextlist; push E.addr; push i; q:=0; push q}

Clist{pop q;pop i;pop E.addr;pop Si.nextlist;S.nextlist:=merge(Si.nextlist, q); push S.nextlist} ⑵Clist→case V :{pop q; pop i; i:=i+1; pop E.addr;

if nextquad ≠0 then backpatch(q, nextquad); q:=nextquad;

gencode(‘if’ E.addr ‘≠’ Vi ‘goto’ Li); push E.addr; push i;

push q}S{pop q; pop i; pop E.addr; pop Si-1.nextlist;

p:=nextquad;

gencode(‘goto -’); gencode(Li‘:’); Si.nextlist:=merge(Si.nextlist, p);

Si.nextlist:=merge(Si.nextlist, Si-1.nextlist);

push Si.nextlist; push E.addr; push i; push q}Clist

⑶Clist→default :{pop q; pop i; i:=i+1; pop E.addr;

if nextquad ≠0 then backpatch(q, nextquad); q:=nextquad;

gencode(‘if’ E.addr ‘≠’ Vi ‘goto’ Vi+1); push E.addr; push i;

push q}S{pop q; pop i; pop E.addr; pop Si-1.nextlist;

p:=nextquad;

gencode(‘goto -’); gencode(Li‘:’); Si.nextlist:=merge(Si.nextlist, p);

Si.nextlist:=merge(Si.nextlist, Si-1.nextlist); push Si.nextlist; push E.addr; push i; push q}

7. 过程调用和返回语句的翻译

过程调用和返回语句的文法如下所示: S → call id(Elist) Elist →Elist, E | E S → return E

过程调用语句的翻译模式如下所示: ⑴ S→call id (Elist) {n :=0;

repeat

n:=n+1;

从queue的队首取出一个实参地址p;

gencode('param', -, -, p); until queue为空; gencode('call', id.addr, n, -)}

4

⑵ Elist→Elist, E{将E.addr添加到queue的队尾}

⑶ Elist→E{初始化queue,然后将E.addr加入到queue的队尾。} 过程返回语句的翻译模式为:

S → return E{if 需要返回结果 then gencode(‘:=’, E.addr, -, F);

gencode(‘ret’, -, -, -)}

其中,F是存放结果的指定单元,四元式(‘ret’, -, -, -)执行如下操作: ⑴ 恢复主调程序的寄存器内容; ⑵ 释放过程运行时所占用的数据区; ⑶ 按返回地址返回到主调程序。

8. 输入输出语句的翻译

带I/O参数的程序语句和输入输出语句的文法如下所示:

P → prog id (input, output) D ; S S → read (List) | readln(List) S → write (Elist) | writeln(Elist)

带I/O参数的程序语句和输入输出语句的翻译方案如下所示:

P→ prog id (Parlist) M D ; S Parlist→ input(ε | , output)

S→ (read | readln) (N List); {n:=0;

repeat

move(Queue, in);

gencode(‘par’, ‘in’, -, -); n:=n+1;

until Queue为空;

gencode(‘call’, ‘SYSIN’, n-1, -);}

List→id, L (ε|List)

S→ (write| writeln) (Elist); { n:=0;

repeat

move(Queue, in);

gencode(‘par’, ‘out’, -, -); n:=n+1;

until Queue为空;

gencode(‘call’, ‘SYSOUT’, n, ‘w’)}

/*n为输出参数个数,w是输出操作类型*/

EList→E, K (ε|EList)

M→ε {gencode(‘prog’, id, y, -)} /*y的值表示input,output或两者皆有*/ N→ε {设置一个语义队列Queue} L→ε {T:=entry(id); add(Queue, T)} K→ε {T:= E.addr; add(Queue, T)}

5


语言的语法及其翻译方案.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:小学四年级下册综合实践活动教案(上海科技教育出版社)2

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: