Homework
- 2012.12.8:
W:
7.8, 7.10
- 2012.12.1:
W:
6.12, 6.14, 6.16, 7.4
- 2012.11.24:
W:
6.2, 6.3, 6.6
- 2012.11.17:
W:
5.9 修改5.3.3节(类型检查)的翻译方案,使之能处理:
(a) 各种有值语句。赋值语句的值是赋值号右边的表达式的值,条件语句
或循环语句的值是语句体的值,语句表的值是表中最后一个语句的值。
(b) 布尔表达式。加上逻辑算符and, or 及not和关系算符的产生式。
然后给出适当的翻译规则,它们检查这些表达式的类型。
5.13, 5.14
- 2012.11.10:
W:
4.13 下面是构造语法树的一个S属性定义。将这里的语义规则翻译成LR翻译器的栈操作代码段。
E → E1 + T
E.nptr = mkNode ('+', E1.nptr, T.nptr)
E → E1 – T
E.nptr = mkNode ('–', E1.nptr, T.nptr)
E → T
E.nptr = T. nptr
T →( E )
T.nptr = E. nptr
T → id
T.nptr = mkLeaf ( id, id.entry)
T → num
T.nptr = mkLeaf ( num, num.val)
4.15 Pascal语言的类型声明的语法及把类型填入符号表的语法制导定义如下:
D → L : T
L.in = T. type
L → L1 , id
addType (id. entry, L.in)
L1.in = L. in
L → id
addType (id. entry, L.in)
T → integer
T.type = integer
T → real
T.type = real
尝试用先分析后翻译的方法,构造非终结符D和L的翻译函数。
- 2012.11.3:
W:
4.5 给出对表达式求导数的语法制导定义,表达式由+和*作用于变量x和常数组成,
如x*(3*x + x*x)
,并假定没有任何化简,
例如将3*x翻译成3*1+0*x。
4.10 文法如下:
S → ( L ) | a
L → L , S | S
(a) 写一个翻译方案,它输出每个a的嵌套深度。
例如,对于句子( a , ( a , a) ),输出的结果是1 2 2。
(b) 写一个翻译方案,它打印出每个a在句子中是第几个字符。
例如,当句子是( a , ( a , ( a , a ) , (a) ) )时,
打印的结果是2 5 8 10 14。
- 2012.10.27:
W:
3.31 为语言
L = { w | w ∈ (a | b)*
并且在w的任何前缀中,a的个数不少于b的个数}
写三个文法,它们分别是LR(1)的、二义的和非二义且非LR(1)的。
- 2012.10.20:
W:
3.20 (a) 证明下面文法
S → AaAb| BbBa
A → ε
B → ε
是LL(1)文法,但不是SLR(1)文法。
3.21 证明下面文法
S → Aa| bAc | dc | bda
A → d
是LALR(1)文法,但不是SLR(1)文法。
- 2012.10.13:
W:
3.18. 考虑下面的文法
E → E + T | T
T → T F | F
F → F* | a | b
(a) 为此文法构造SLR分析表。
(b) 构造LALR分析表。
- 2012.10.6:
P2: (略)
W:
3.10. 构造下面文法的LL(1)分析表。
D → TL
T → int | real
L → id R
R → , id R |ε
3.11 下面的文法是否为LL(1)文法?说明理由。
S → A B | P Q x
A → x y
B → b c
P → d P |ε
Q → a Q |ε
- 2012.9.22:
P1:
1) 阅读PLO编译器源码
(doc),
编译运行PL0编译器,使之能解释执行PL0程序;
2) 扩展PLO编译器的词法分析(getsym()
),
使之能识别、处理多行注释(/*...*/
)、八进制数、十六进制数。
W: 3.4. 文法
R → R '|' R | R R | R* | ( R ) | a | b
产生字母表{a, b}上所有不含ε的正规式。注意,第一条竖线加了引号,它是正规式的或运算符号,而不是文法产生式右部各选择之间的分隔符,另外*在这儿是一个普通的终结符。该文法是二义的。
(a) 证明该文法产生字母表{a, b}上的所有正规式。
(b) 为该文法写一个等价的非二义文法。它给予算符*、连接和 | 的优先级和结合性同2.2节中定义的一致。
(c) 按上面两个文法构造句子ab |b*a的分析树。
- 2012.9.15:
2.11