厦大软工编译原理作业第四章 自顶向下语法分析

第四章 自顶向下语法分析

1、对文法G[S]

S→a|∧|(T)

T→T,S|S

(1) 给出(a,(a,a))和(((a,a),∧,(a)),a)的最左推导。

(a,(a,a)):

S->(T)-->(S,S)-->(a,S)-->(a,(T))-->(a,(T,S))-->(a,(S,S))-->(a,(a,a))

(((a,a),∧,(a)),a):

S->(T)-->(T,S)-->(S,S)-->((T),S)-->((T,S),S)-->((T,S,S),S)-->((S,S,S),S)-->(((T),S,S),S)-->(((T,S),S,S),S)-->(((S,S),S,S),S)-->(((a,a),S,S),S)-->(((a,a),∧,S),S)-->(((a,a),∧,(T)),S)-->(((a,a),∧,(S)),S) -->(((a,a),∧,(a)),S)-->(((a,a),∧,(a)),a)

(2) 对文法G,进行改写,然后对每个非终结符写出不带回溯的递归子程序。

消除直接左递归:T-->T,S,把文法G改写为:

S->a

S-->∧

S-->(T)

T-->SN

N-->,SN

N-->ε

不带回溯的递归子程序:

Step1:计算FIRST集:

FIRST(S)={a,∧,(}

FIRST(T)=FIRST(S)={a,∧,(}

FIRST(N)={,,ε}

Step2:计算FOLLOW集:

FOLLOW(S)=(FIRST(N)-{ε})UFOLLOW(T)U{#}={#,,,)}

FOLLOW(T)=FIRST())={)}

FOLLOW(N)=FOLLOW{T}={)}

列表如下:

非终结符

FIRST集

FOLLOW集

S

{a,∧,(}

{#,,,)}

T

{a,∧,(}

{)}

N

{,,ε}

{)}

Step3:计算SELECT集:

SELECT(S-->a)={a}

SELECT(S-->∧)={∧}

SELECT(S-->(T))={(}

SELECT(T-->SN)=FIRST(S)={a,∧,(}

SELECT(N-->,SN}={,}

SELECT(N-->ε)=FOLLOW(N)={)}

Step4:写出递归子程序

void ParseS()

{

switch(lookahead)

{

case a:

MatchToken(a);

break;

case ∧:

MatchToken(∧);

break;

case (:

MatchToken(();

ParseT();

MatchToken());

default:

printf("syntax error \n");

exit(0);

}

}

void ParseT()

{

switch(lookahead)

{

case a,∧,(:

ParseS();

ParseN();

break;

default:

printf("syntax error \n");

exit(0);

}

}

void ParseN()

{

switch(lookahead)

{

case ,:

MatchToken(,);

ParseS();

ParseN();

break;

case ):

break;

default:

printf("syntax error \n");

exit(0);

}

}

(3) 经改写后的文法是否是LL(1)的?给出它的预测分析表。

由(2)得:

SELECT(S-->a)∩SELECT(S-->∧)∩SELECT(S-->(T))={a}∩{∧}∩{(}=∅

SELECT(N-->,SN}∩SELECT(N-->ε)={,}∩{)}=∅

因此改写后的文法是LL(1)文法。

预测分析表:

a

(

)

,

S

-->a

-->∧

-->(T)

T

-->SN

-->SN

-->SN

N

-->ε

-->,SN

(4) 给出输入串(a,a)#的分析过程,并说明该串是否为G 的句子。

当前输入符

剩余输入符

所用产生式

#S

(

a,a)#

S-->(T)

#)T(

(

a,a)#

#)T

a

,a)#

T-->SN

#)NS

a

,a)#

S-->a

#)Na

a

,a)#

#)N

,

a)#

N-->SN

#)NS,

,

a)#

#)NS

a

)#

S-->a

#)Na

a

)#

#)N

)

#

N-->ε

#)

)

#

#

#

因此输入串(a,a)#是文法G的句子。

2、已知文法G[S]:

S→MH|a

H→LSo|ε

K→dML|ε

L→eHf

M→K|bLM

判断G 是否是LL(1)文法,如果是,构造LL(1)分析表。

计算各非终结符的FIRST集和FOLLOW集:

FIRST(S)={a}+FIRST(M)+FIRST(H)={a,b,d,e,ε}

FIRST(H)={ε}+FIRST(L)+

FIRST(K)={d,ε}

FIRST(L)={e}

FIRST(M)=FIRST(K)+{b}={d,b,ε}

FOLLOW(S)={#,o}

FOLLOW(H)=FOLLOW(S)+{f}={#,o,f}

FOLLOW(K)=FOLLOW(M)={e,#,o}

FOLLOW(L)=FIRST(M)-{ε}+FOLLOW(M)+FOLLOW(K)={b,d,e,#,o}

FOLLOW(M)=FIRST(L)+FIRST(H)-{ε}+FOLLOW(S)={e,#,o}

FIRST集

FOLLOW集

S

{a,b,d,e,ε}

{#,o}

H

{e,ε}

{#,f,o}

K

{d,ε}

{e,#,o}

L

{e}

{#,o,b,d,e}

M

{b,d,ε}

{e,#,o}

因此,SELECT集计算如下:

SELECT(S-->MH)=FIRST(M)}-{ε}+FOLLOW(S)={b,d,e,o,#}

SELECT(S-->a)={a}

所以SELECT(S-->MH)∩SELECT(S-->a)=∅

SELECT(H-->LSo)=FIRST(L)={e}

SELECT(H-->ε)=FOLLOW(H)={#,f,o}

所以SELECT(H-->LSo)∩SELECT(H-->ε)=∅

SELECT(K-->dML)={d}

SELECT(K-->ε)=FOLLOW(K)={e,#,o}

所以SELECT(K-->dML)∩SELECT(K-->ε)=∅

SELECT(L-->eHf)={e}

SELECT(M-->K)=FIRST(K)-{ε}+FOLLOW(M)={d,e,#,o}

SELECT(M-->bLM)={b}

所以SELECT(M-->K)∩SELECT(M-->bLM)=∅

综上所述,该文法是LL(1)文法。

故预测分析表如下:

a

b

d

e

f

o

#

S

-->a

-->MH

-->MH

-->MH

-->MH

-->MH

H

-->LSo

-->ε

-->ε

-->ε

K

-->dML

-->ε

-->ε

-->ε

L

-->eHf

M

-->bLM

-->K

-->K

-->K

-->K

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值