「CS143 - Compilers Notes」 PA1

PA1目的:用cool语言写一个解析器。
version:Edx

PA-1

PA1

e的具体操作:

栈顶 解释
s 出栈s,将栈顶两个交换站内位置
+ 出栈+,将栈顶两个出站相加后入栈
空栈数字 跳过此次操作

其余要求:

  1. 输入前要有>并且和输入之间无空格
  2. d操作: 每打印完一个元素要换行

坑(已踩)

cool 语法

  • Blocks(即{}) 中不能定义属性(即变量)
  • Blocks(即{}) 中所有语句后都要;
  • if <exp0> then <exp1> else <exp2> fi 中的 else <exp2> 不能省略
  • String.substr(index, length)index base 0length > 0
  • 类的方法和属性的作用域不可定义
  • 类的方法为全局
  • 类的属性为私有

其他

直接运行Edx中的spim一切正常,但是会报一条警告(/usr/class/bin/spim: line 56: [: !=: unary operator expected),为了消除这个警告需要改写了$CLASS/bin中的spim脚本,改写方式如下。

$CLASS 指 Edx 中 Installing Directly on Linux 下载下来的包,解压后的目录位置

1
2
3
4
5
6
7
8
9
10
#spim:42  如果的python Version>=3,则需要更改
print os.path.abspath(sys.argv[1])
#spim:39 -P -> -p
if [ `type -p asdfpython` ]; then
#spim:56
if [ "${1:0:1}" != "-" ]; then
#spim:61
if [ $# -ge 1 ]; then
set -- "$abspath" "${@:2}"
fi

代码实现

思路: 用cool提供的String类型来模拟栈,然后实现下c++中有的pop()push()empty()等方法。

unix/linux> make stack.s进行编译
unix/linux> make test 进行测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
(*
* CS164 Fall 94
*
* Programming Assignment 1
* Implementation of a simple stack machine.
*
* Skeleton file
*)

class Main inherits IO {
stack : StackCommand <- new StackCommand;

main() : Object {
stack.parse()
};

};

class StackCommand {

-- attributes
io : IO <- new IO;
ta : Int;
tb : Int;
inc : String;
tc0 : String;
tc1 : String;
flg : Bool;
stk : String;
convert : A2I <- new A2I;

-- methods
format() : Object {
io.out_string(">")
};

input() : Object {
{
io.out_string(">");
inc <- io.in_string();
}
};

display(output : String) : Object {
let i : Int <- 0 in {
while i < output.length() loop {
io.out_string(output.substr(i, 1).concat("\n"));
i <- i+1;
}
pool;
}
};

spush(c : String) : Object {
stk <- c.concat(stk)
};

spop() : String {
{
tc0 <- "";
if not sempty() then
{
tc0 <- stk.substr(0, 1);
if stk.length() = 1 then stk <- "" else stk <- stk.substr(1, stk.length() - 1) fi;
}
else tc0
fi;
tc0; --return tc
}
};

sempty() : Bool {
stk.length() = 0
};

switch() : Object {
{
tc1 <- spop();
spush(spop().concat(tc1));
}
};

add() : Object {
{
ta <- convert.a2i(spop());
tb <- convert.a2i(spop());
spush(convert.i2a(ta + tb));
}
};

(*
eval() <- implemented the 'e'

when top is 's' pop 's' and switch next two items in the stack
when top is '+' pop '+' and insert the sum of next two items to the stack
*)

eval() : Object {
{
-- check the size of the stack
if not sempty() then
{
tc1 <- spop();
if tc1 = "s" then switch() else
if tc1 = "+" then add() else
{ "RARA!"; } --need trash todo
fi fi;
} else { "RARA"; }
fi;
}
};

parse() : Object {
{
flg <- true;
while flg loop {
input();
if inc = "x" then flg <- false
else if inc = "d" then display(stk)
else if inc = "e" then eval()
else spush(inc)
fi fi fi;
} pool;
}
};

};

参考资料

The Cool Refrence Manual , by Alex Aiken
A Tour of the Cool Support Code , by Alex Aiken



--------------------------END--------------------------
喜欢的话,不妨请我喝杯奶茶(≧∇≦)ノ