练习
本节阅读量:这一页适合读完第一章后回头做。不要急着一次做完,先能看懂输出,再尝试改代码。
练习 1:手画 AST
画出下面程序的 AST:
|
|
参考形状:
|
|
练习 2:追踪 parser
不用写代码,只写出 parser 的动作顺序。
程序:
|
|
参考形式:
|
|
这个练习的目的不是背函数名,而是确认你知道:
|
|
练习 3:手写 IR
给下面程序写出计算步骤:
|
|
参考形式:
|
|
练习 4:观察真实输出
运行:
|
|
对照三个输出:
|
|
练习 5:手写简单汇编
尝试给下面程序手写汇编:
|
|
目标结果是 42。
你应该至少用到:
|
|
练习 6:改一个示例
新建或修改一个示例文件,让它表示:
|
|
然后依次运行:
|
|
检查解释器结果、IR 和汇编是否能对应起来。
练习 7:自己实现减法
把第一章的语言扩展一点点,让它支持二元减法:
|
|
这个程序的结果应该是 7。
再试一个嵌套例子:
|
|
这个程序的结果应该是 12。
你可以按这条线索改:
|
|
注意,-1 仍然是一个整数;(- 10 1) 才是减法表达式。
改完后至少运行:
|
|
检查解释器结果、IR 和汇编运行结果是不是一致。
练习 8:给坏程序写错误信息
这一题不要求加入新语法。目标是让错误更清楚。
试着运行或构造下面这些坏程序:
|
|
然后改 parser,让它们失败时尽量说清楚原因。
你可以先做到这种程度:
|
|
这道题的重点不是写出很漂亮的错误系统,而是练习 parser 在哪里知道“现在不对了”。
练习 9:手算栈槽
不要先运行编译器。先手算下面程序可能需要哪些临时变量:
|
|
写出类似这样的表:
|
|
然后运行:
|
|
对照真实 IR 和汇编,看看你的临时变量顺序、栈槽位置和编译器是否一致。
不一致也没关系。只要解释器结果和汇编结果一致,不同的临时变量安排也可以是正确的。
练习 10:观察退出码截断
第一章的汇编程序用返回值看结果。这个办法很方便,但它不是完整的数字输出。
试试这些程序:
|
|
每个程序都编译、链接、运行:
|
|
记录你看到的结果。
想一想:
|
|
这道题是为了确认一件事:退出码只是操作系统保存的一小段结果,不等于语言以后真正的打印功能。
练习 11:想一想下一章
如果下一章加入变量:
|
|
和现在的:
|
|
会有什么不同?
先不用实现,只要想:
|
|
这就是第二章要解决的问题。
本节目录