Kernel FP 语法分析完成
语法分析器终于完成了,总共花了7个小时的时间。其中遇到了一些小问题,譬如lambda expression的\param->expression和let-in expression的let declaration-list in expression里面的expression需要尽可能长的解决办法。因为用了Vczh Syngram,所以不得不调整出符合需求的文法。
为了大概看一看文法有没有写对,我写了一个程序,读入 KernelFP语言写的一份代码,将其格式化并输出。
输入代码如下:
1
type
int
2 type char
3 type bool = true | false
4 type list T = empty | list T (list T)
5
6 func iadd:: int -> int -> int alias " add "
7 func isub:: int -> int -> int alias " sub "
8 func imul:: int -> int -> int alias " mul "
9 func idiv:: int -> int -> int alias " div "
10 func imod:: int -> int -> int alias " mod "
11 func ilg:: int -> int -> bool alias " ilg "
12 func ism:: int -> int -> bool alias " ism "
13 func iequ:: int -> int -> bool alias " iequ "
14 func chr:: int -> char alias " chr "
15 func ord:: char -> int alias " ord "
16
17 func not:: bool -> bool
18 def not a = select a of
19 case true : false
20 case false : true
21 end
22
23 func and:: bool -> bool -> bool
24 def and a b = select a of
25 case true : b
26 case false : false
27 end
28
29 func or:: bool -> bool -> bool
30 def or a b = select a of
31 case true : true
32 case false : b
33 end
34
35 func xor:: bool -> bool -> bool
36 def xor a b = select a of
37 case true : not b
38 case false : b
39 end
40
41 func T if :: bool -> T -> T
42 def if cond t f = select cond of
43 case true : t
44 case false : f
45 end
46
47 func ineg:: int -> int
48 def ineg num = isub 0 num
49
50 func coffset:: char -> int -> char
51 def coffset c i = chr (iadd (ord c) i)
52
53 func itoa:: int -> list char
54 def itoa a = if (iequ a 0 ) (list ' 0 ' empty) ( if (ism a 0 )
55 (list ' - ' (itoa (ineg a)))
56 let
57 func _itoa:: int -> (list char ) -> (list char )
58 def _itoa a chs = select a of
59 case 0 : chs
60 else : _itoa (div a 10 ) (list (coffset ' 0 ' (mod a 10 )) chs)
61 end
62 in _itoa a empty)
63
64 func atoi::list char -> int
65 def atoi chs = select chs of
66 case empty : 0
67 case list ' - ' chs : ineg (atoi chs)
68 case c chs : iadd (imul 10 (isub (ord c) (ord ' 0 ' ))) (atoi chs)
69 end
2 type char
3 type bool = true | false
4 type list T = empty | list T (list T)
5
6 func iadd:: int -> int -> int alias " add "
7 func isub:: int -> int -> int alias " sub "
8 func imul:: int -> int -> int alias " mul "
9 func idiv:: int -> int -> int alias " div "
10 func imod:: int -> int -> int alias " mod "
11 func ilg:: int -> int -> bool alias " ilg "
12 func ism:: int -> int -> bool alias " ism "
13 func iequ:: int -> int -> bool alias " iequ "
14 func chr:: int -> char alias " chr "
15 func ord:: char -> int alias " ord "
16
17 func not:: bool -> bool
18 def not a = select a of
19 case true : false
20 case false : true
21 end
22
23 func and:: bool -> bool -> bool
24 def and a b = select a of
25 case true : b
26 case false : false
27 end
28
29 func or:: bool -> bool -> bool
30 def or a b = select a of
31 case true : true
32 case false : b
33 end
34
35 func xor:: bool -> bool -> bool
36 def xor a b = select a of
37 case true : not b
38 case false : b
39 end
40
41 func T if :: bool -> T -> T
42 def if cond t f = select cond of
43 case true : t
44 case false : f
45 end
46
47 func ineg:: int -> int
48 def ineg num = isub 0 num
49
50 func coffset:: char -> int -> char
51 def coffset c i = chr (iadd (ord c) i)
52
53 func itoa:: int -> list char
54 def itoa a = if (iequ a 0 ) (list ' 0 ' empty) ( if (ism a 0 )
55 (list ' - ' (itoa (ineg a)))
56 let
57 func _itoa:: int -> (list char ) -> (list char )
58 def _itoa a chs = select a of
59 case 0 : chs
60 else : _itoa (div a 10 ) (list (coffset ' 0 ' (mod a 10 )) chs)
61 end
62 in _itoa a empty)
63
64 func atoi::list char -> int
65 def atoi chs = select chs of
66 case empty : 0
67 case list ' - ' chs : ineg (atoi chs)
68 case c chs : iadd (imul 10 (isub (ord c) (ord ' 0 ' ))) (atoi chs)
69 end
输出代码如下:
1
表达式1
/
1
2 type int
3
4 type char
5
6 type bool = ( true | false )
7
8 type list T = (empty | (list T (list T)))
9
10 func iadd :: (( int -> int ) -> int ) alias " add "
11
12 func isub :: (( int -> int ) -> int ) alias " sub "
13
14 func imul :: (( int -> int ) -> int ) alias " mul "
15
16 func idiv :: (( int -> int ) -> int ) alias " div "
17
18 func imod :: (( int -> int ) -> int ) alias " mod "
19
20 func ilg :: (( int -> int ) -> bool ) alias " ilg "
21
22 func ism :: (( int -> int ) -> bool ) alias " ism "
23
24 func iequ :: (( int -> int ) -> bool ) alias " iequ "
25
26 func chr :: ( int -> char ) alias " chr "
27
28 func ord :: ( char -> int ) alias " ord "
29
30 func not :: ( bool -> bool )
31 def not a =
32 select a of
33 case true : false
34 case false : true
35 end
36
37 func and :: (( bool -> bool ) -> bool )
38 def and a b =
39 select a of
40 case true : b
41 case false : false
42 end
43
44 func or :: (( bool -> bool ) -> bool )
45 def or a b =
46 select a of
47 case true : true
48 case false : b
49 end
50
51 func xor :: (( bool -> bool ) -> bool )
52 def xor a b =
53 select a of
54 case true : (not b)
55 case false : b
56 end
57
58 func T if :: (( bool -> T) -> T)
59 def if cond t f =
60 select cond of
61 case true : t
62 case false : f
63 end
64
65 func ineg :: ( int -> int )
66 def ineg num = ((isub 0 ) num)
67
68 func coffset :: (( char -> int ) -> char )
69 def coffset c i = (chr ((iadd (ord c)) i))
70
71 func itoa :: ( int -> (list char ))
72 def itoa a = ((( if ((iequ a) 0 )) ((list ' 0 ' ) empty)) ((( if ((ism a) 0 )) ((list ' - ' ) (itoa (ineg a))))
73 (let
74 func _itoa :: (( int -> (list char )) -> (list char ))
75 def _itoa a chs =
76 select a of
77 case 0 : chs
78 else : ((_itoa ((div a) 10 )) ((list ((coffset ' 0 ' ) ((mod a) 10 ))) chs))
79 end
80 in ((_itoa a) empty))))
81
82 func atoi :: ((list char ) -> int )
83 def atoi chs =
84 select chs of
85 case empty : 0
86 case ((list ' - ' ) chs) : (ineg (atoi chs))
87 case (c chs) : ((iadd ((imul 10 ) ((isub (ord c)) (ord ' 0 ' )))) (atoi chs))
88 end
89
2 type int
3
4 type char
5
6 type bool = ( true | false )
7
8 type list T = (empty | (list T (list T)))
9
10 func iadd :: (( int -> int ) -> int ) alias " add "
11
12 func isub :: (( int -> int ) -> int ) alias " sub "
13
14 func imul :: (( int -> int ) -> int ) alias " mul "
15
16 func idiv :: (( int -> int ) -> int ) alias " div "
17
18 func imod :: (( int -> int ) -> int ) alias " mod "
19
20 func ilg :: (( int -> int ) -> bool ) alias " ilg "
21
22 func ism :: (( int -> int ) -> bool ) alias " ism "
23
24 func iequ :: (( int -> int ) -> bool ) alias " iequ "
25
26 func chr :: ( int -> char ) alias " chr "
27
28 func ord :: ( char -> int ) alias " ord "
29
30 func not :: ( bool -> bool )
31 def not a =
32 select a of
33 case true : false
34 case false : true
35 end
36
37 func and :: (( bool -> bool ) -> bool )
38 def and a b =
39 select a of
40 case true : b
41 case false : false
42 end
43
44 func or :: (( bool -> bool ) -> bool )
45 def or a b =
46 select a of
47 case true : true
48 case false : b
49 end
50
51 func xor :: (( bool -> bool ) -> bool )
52 def xor a b =
53 select a of
54 case true : (not b)
55 case false : b
56 end
57
58 func T if :: (( bool -> T) -> T)
59 def if cond t f =
60 select cond of
61 case true : t
62 case false : f
63 end
64
65 func ineg :: ( int -> int )
66 def ineg num = ((isub 0 ) num)
67
68 func coffset :: (( char -> int ) -> char )
69 def coffset c i = (chr ((iadd (ord c)) i))
70
71 func itoa :: ( int -> (list char ))
72 def itoa a = ((( if ((iequ a) 0 )) ((list ' 0 ' ) empty)) ((( if ((ism a) 0 )) ((list ' - ' ) (itoa (ineg a))))
73 (let
74 func _itoa :: (( int -> (list char )) -> (list char ))
75 def _itoa a chs =
76 select a of
77 case 0 : chs
78 else : ((_itoa ((div a) 10 )) ((list ((coffset ' 0 ' ) ((mod a) 10 ))) chs))
79 end
80 in ((_itoa a) empty))))
81
82 func atoi :: ((list char ) -> int )
83 def atoi chs =
84 select chs of
85 case empty : 0
86 case ((list ' - ' ) chs) : (ineg (atoi chs))
87 case (c chs) : ((iadd ((imul 10 ) ((isub (ord c)) (ord ' 0 ' )))) (atoi chs))
88 end
89
今晚和明天要想出一个解决带有模板参数的类型推导的解决办法。因为实际上当你写下
func T1 T2 name::T1->T2
def name a = ....
的时候,T1和T2不一定能够取到所有类型,而且T1和T2也不一定没有关系。所以如果你不写func头的话,一个默认的,不影响语义的func头是可以生成出来的,直接用模板就可以了。所以对于这门最小内核语言来说,这个语法糖是可以省略的。
譬如说:
func T1 T2 T3 makelist :: T1 -> T2 -> T3
def makelist a b = list a (list b empty)
在这个描述下,T1必须跟T2相同,而且T3必须是list T1这种类型。所以,你把函数头改成了func T makelist::T->T->list T,也是丝毫没有影响的。