-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathparser.mly
114 lines (97 loc) · 2.46 KB
/
parser.mly
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
%{
open Syntax
%}
%token TINT
%token TBOOL
%token TFORGET
%token TFREE
%token <Syntax.name> VAR
%token <int> INT
%token TRUE FALSE
%token PLUS
%token MINUS
%token TIMES
%token EQUAL LESS
%token IF THEN ELSE
%token FUN ARROW
%token REC IS
%token COLON
%token LPAREN RPAREN
%token LET IN
%token DO
%token TO
%token SEMICOLON2
%token RETURN THUNK FORCE
%token QUIT
%token USE
%token <string>STRING
%token EOF
%start toplevel
%type <Syntax.toplevel_cmd list> toplevel
%right TO LET
%right ARROW
%nonassoc FUN REC
%nonassoc IF THEN ELSE
%nonassoc EQUAL LESS
%left PLUS MINUS
%left TIMES
%right TFREE TFORGET
%%
toplevel:
| EOF { [] }
| lettop { $1 }
| exprtop { $1 }
| cmdtop { $1 }
lettop:
| def EOF { [$1] }
| def lettop { $1 :: $2 }
| def SEMICOLON2 toplevel { $1 :: $3 }
exprtop:
| expr EOF { [Expr $1] }
| expr SEMICOLON2 toplevel { Expr $1 :: $3 }
cmdtop:
| cmd EOF { [$1] }
| cmd SEMICOLON2 toplevel { $1 :: $3 }
cmd:
| USE STRING { Use $2 }
| QUIT { Quit }
def:
| LET VAR EQUAL expr { Def ($2, $4) }
| DO VAR EQUAL expr { RunDef ($2, $4) }
expr:
| app { $1 }
| arith { $1 }
| boolean { $1 }
| LET VAR EQUAL expr IN expr %prec LET { Let ($2, $4, $6) }
| expr TO VAR IN expr %prec TO { To ($1, $3, $5) }
| IF expr THEN expr ELSE expr { If ($2, $4, $6) }
| FUN VAR COLON ty ARROW expr %prec FUN { Fun ($2, $4, $6) }
| REC VAR COLON ty IS expr %prec REC { Rec ($2, $4, $6) }
app:
| non_app { $1 }
| FORCE non_app { Force $2 }
| RETURN non_app { Return $2 }
| THUNK non_app { Thunk $2 }
| app non_app { Apply ($1, $2) }
non_app:
| VAR { Var $1 }
| TRUE { Bool true }
| FALSE { Bool false }
| INT { Int $1 }
| LPAREN expr RPAREN { $2 }
arith:
| MINUS INT { Int (-$2) }
| expr PLUS expr { Plus ($1, $3) }
| expr MINUS expr { Minus ($1, $3) }
| expr TIMES expr { Times ($1, $3) }
boolean:
| expr EQUAL expr { Equal ($1, $3) }
| expr LESS expr { Less ($1, $3) }
ty:
| TINT { VInt }
| TBOOL { VBool }
| ty ARROW ty { CArrow ($1, $3) }
| TFORGET ty { VForget $2 }
| TFREE ty { CFree $2 }
| LPAREN ty RPAREN { $2 }
%%