-
Notifications
You must be signed in to change notification settings - Fork 0
/
slp.grm
128 lines (118 loc) · 4.13 KB
/
slp.grm
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
128
(* This version of the parser will interpret the program *)
structure Table =
struct
type key = string;
type value = int;
type cell = key * value;
type table = cell list;
val empty = [];
exception Fail;
fun update (id, value, table) = (id, value) :: table;
fun lookup (id, []) = raise Fail
| lookup (id, (s, v)::rest) =
if id = s
then v
else lookup (id, rest);
end
%%
%term SEMICOLON
| ASSIGN
| PRINT
| LPAREN
| RPAREN
| ID of string
| INT of int
| PLUS
| MINUS
| TIMES
| DIVIDE
| COMMA
| EOF
%nonterm prog of Table.table
| stm of Table.table -> Table.table
| exp of Table.table -> Table.table * int
| exps of Table.table -> Table.table * int
%pos int
%start prog
%name Slp
%verbose
%noshift EOF
%eop EOF
%right SEMICOLON COMMA
%left PLUS MINUS
%left TIMES DIVIDE
%%
prog: stm (stm (Table.empty))
stm: ID ASSIGN exp (fn table =>
let
val (newTable, value) = (exp table)
in
Table.update (ID, value, newTable)
end)
| PRINT LPAREN exps RPAREN (fn table =>
let
val (newTable, value) = exps table
in
newTable
end)
| stm SEMICOLON stm (fn table => stm2 (stm1 table))
exps: exp (fn table =>
let
val (newTable, value) = exp table
in
(print (Int.toString value); print "\n"; (newTable, value))
end)
| exps COMMA exp (fn table =>
let
val (newTable, _) = exps table
in
let
val (newTable, value) = exp newTable
in
(print (Int.toString value); print "\n"; (newTable, value))
end
end)
exp: INT (fn table => (table, INT))
| ID (fn table => (table, Table.lookup (ID, table)))
| exp PLUS exp (fn table =>
let
val (newTable, value1) = exp1 table
in
let
val (newTable, value2) = exp2 newTable
in
(newTable, value1 + value2)
end
end)
| exp MINUS exp (fn table =>
let
val (newTable, value1) = exp1 table
in
let
val (newTable, value2) = exp2 newTable
in
(newTable, value1 - value2)
end
end)
| exp TIMES exp (fn table =>
let
val (newTable, value1) = exp1 table
in
let
val (newTable, value2) = exp2 newTable
in
(newTable, value1 * value2)
end
end)
| exp DIVIDE exp (fn table =>
let
val (newTable, value1) = exp1 table
in
let
val (newTable, value2) = exp2 newTable
in
(newTable, value1 div value2)
end
end)
| stm COMMA exp (fn table => exp (stm table))
| LPAREN exp RPAREN (fn table => exp table)