HNU 编译系统 语法制导翻译练习题(选自龙书)

因为后面几章的作业题量较少,且不能很充分地覆盖全部知识点及考点,因此在龙书上又选了几道题作为额外补充练习。由于未找到龙书的标准答案,所以这里仅贴出了我自己做的答案,可能有误。

第 1 题

![[Pasted image 20251121224451.png]]

L属性的SDD:
属性定义:

  • S.val: S属性,表示整个数字的十进制值。
  • L.val: S属性,表示L序列的十进制值。
  • L.side: L属性,表示L在小数点的哪一边,1表示左,0表示右。
  • L.len: S属性,表示L序列的数字位数。
  • B.val: S属性,表示二进制位的值(0或1)。
1. S -> L1 . L2   {S.val = L1.val + L2.val;
				   L1.side = 1;
				   L2.side = 0;}
2. S -> L         {S.val = L.val;
				   L.side = 1;}
3. L -> L1 B      {if (L.side == 1) {L.val = L1.val * 2 + B.val;}
				   else {L.val = L1.val + B.val * pow(2, -L1.len);}
				   L.len = L1.len + 1;
				   L1.side = L.side;}
4. L -> B         {if (L.side == 1) L.val = B.val;
				   else L.val = B.val / 2.0;
				   L.len = 1;
				   B.side = L.side;}
5. B -> 0         {B.val = 0;}
6. B -> 1         {B.val = 1;}

S属性的SDD:
属性定义:

  • S.val: S属性,表示整个数字的十进制值。
  • L.val: S属性,表示L序列的十进制值。
  • L.len: S属性,表示L序列的数字位数。
  • B.val: S属性,表示二进制位的值(0或1)
1. S -> L1 . L2   {S.val = L1.val + L2.val * pow(2, -L2.len);}
2. S -> L         {S.val = L.val;}
3. L -> L1 B      {L.val = L1.val * 2 + B.val;
				   L.len = L1.len + 1;}
4. L -> B         {L.val = B.val;
				   L.len = 1;}
5. B -> 0         {B.val = 0}
6. B -> 1         {B.val = 1}

第 2 题

![[Pasted image 20251122172209.png]]

(1)属性定义:

  • E.type: S属性,表示表达式E的类型。
  • L.type: S属性,表示项T的类型。
    SDD如下:
1. E -> E1 + T    {if (E1.type == T.type) {E.type = E1.type;}
				   else {print("error");}}
2. E -> T         {E.type = T.type;}
3. T -> num.num   {T.type = float;}
4. T -> num       {T.type = int;}

(2)属性定义:

  • E.expression: S属性,表示表达式E的后缀表达式。
  • E.type: S属性,表示表达式E的类型。
  • L.type: S属性,表示项T的类型。
    SDD如下:
1. E -> E1 + T    {if (E1.type == T.type) {E.type = E1.type;}
				   else if (E1.type == int) {E1 = intToFloat(E1);}
				   else {T = intToFloat(T);}
				   E.expression = E1.expression + T + "+";}
2. E -> T         {E.type = T.type;
				   E.expression = T;}
3. T -> num.num   {T.type = float;}
4. T -> num       {T.type = int;}

第 3 题

![[Pasted image 20251122183058.png]]

1. E -> E1 + T    {E.prec = 1;
				   // 处理左子 E1(左子,isRight = false)
				   if (E1.prec < E.prec) leftStr = "(" + E1.str + ")";
				   else leftStr = E1.str;
				   // 处理右子 T(右子,isRight = true)
				   if (T.prec < E.prec || T.prec == E.prec) rightStr = "(" + T.str + ")";
				   else rightStr = T.str;
				   E.str = leftStr + "+" + rightStr;}

2. E -> T         {E.prec = T.prec;
			       E.str  = T.str;}

3. E -> ( E1 )    {E.prec = E1.prec;
				   E.str  = E1.str;}

4. T -> T1 * F    {T.prec = 2;
				   // 左子 T1(左子,isRight = false)
				   if (T1.prec < T.prec) leftStr = "(" + T1.str + ")";
				   else leftStr = T1.str;
				   // 右子 F(右子,isRight = true)
				   if (F.prec < T.prec || F.prec == T.prec) rightStr = "(" + F.str + ")";
				   else rightStr = F.str;
				   T.str = leftStr + "*" + rightStr;}

5. T -> F         {T.prec = F.prec;
				   T.str  = F.str;}

6. F -> id        {F.prec = 3;
				   F.str  = id.lexeme;}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值