-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.mly
194 lines (170 loc) · 4.28 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
%{
(* This parser is implemented with ocamlyacc, not menhir. *)
open Ast
open TypedAst
open Lexing
let parse_error _ =
let start_pos = Parsing.symbol_start_pos () in
let end_pos = Parsing.symbol_end_pos () in
let start_line = string_of_int start_pos.pos_lnum in
let start_char = string_of_int (start_pos.pos_cnum - start_pos.pos_bol) in
let end_line = string_of_int end_pos.pos_lnum in
let end_char = string_of_int (end_pos.pos_cnum - end_pos.pos_bol) in
failwith ("Parse error: ("^start_line^"."^start_char^"-"^end_line^"."^end_char)
%}
%token ASSIGN
%token MATCH
%token WITH
%token PIPE
%token FALSE
%token TRUE
%token IF
%token THEN
%token ELSE
%token PLUS
%token MINUS
%token MULT
%token CONCAT
%token LET
%token REC
%token IN
%token GT
%token LT
%token LTQ
%token GTQ
%token EQ
%token NEQ
%token AND
%token COMMA
%token <string> VAR
%token <string> CONSTR
%token <string> STRING
%token <string> INT
%token LPAREN RPAREN
%token ARROW
%token FUN
%token UNIT
%token EOF
%token TYPE
%token OF
%token <string> TVAR
%token TUNIT
%token TINT
%token TBOOL
%token TSTRING
%token TCONS
%right ARROW
%nonassoc LET
%nonassoc FUN MATCH IF IN
%right PIPE
%nonassoc COMMA
%left GT LT LTQ GTQ EQ NEQ ASSIGN
%right CONCAT
%left PLUS MINUS
%left MULT
%nonassoc VAR LBRACE UNIT INT TRUE FALSE LPAREN STRING
%left CONSTR APP
%left TCONS
/* entry point */
%start expr
%type <Ast.expr> expr
%start typ
%type <TypedAst.typ> typ
%start variant_spec
%type <TypedAst.variant_spec> variant_spec
%start tvar_list
%type <string list> tvar_list
%start constr_list
%type <(string * TypedAst.typ) list> constr_list
%%
expr:
| UNIT {Unit}
| INT {Int (int_of_string $1)}
| TRUE {Bool true}
| FALSE {Bool false}
| STRING {String $1}
| expr PLUS expr { BinOp (Plus, $1, $3) }
| expr MINUS expr { BinOp (Minus, $1, $3) }
| expr MULT expr { BinOp (Times, $1, $3) }
| expr CONCAT expr { BinOp (Concat, $1, $3) }
| expr GT expr { BinOp (Gt, $1, $3) }
| expr LT expr { BinOp (Lt, $1, $3) }
| expr LTQ expr { BinOp (LtEq, $1, $3) }
| expr GTQ expr { BinOp (GtEq, $1, $3) }
| expr EQ expr { BinOp (Eq, $1, $3) }
| expr NEQ expr { BinOp (NotEq, $1, $3) }
| IF expr THEN expr ELSE expr %prec IF
{ If ($2, $4, $6) }
| VAR { Var $1 }
| expr expr %prec APP
{ App ($1, $2) }
| FUN VAR ARROW expr %prec FUN
{ Fun ($2,$4) }
| MATCH expr WITH pattern_matching %prec MATCH
{ Match ($2, $4) }
| MATCH expr WITH PIPE pattern_matching %prec MATCH
{ Match ($2, $5) }
| LET VAR EQ expr IN expr
{ Let ($2,$4,$6) }
| LET REC VAR EQ expr IN expr
{ LetRec ($3,$5,$7) }
| expr COMMA expr %prec COMMA
{ Pair ($1,$3) }
| CONSTR expr %prec CONSTR
{ Variant ($1,$2) }
| LPAREN expr RPAREN %prec LPAREN
{ $2 }
;
pattern_matching:
| pattern ARROW expr PIPE pattern_matching %prec PIPE
{ ($1, $3)::$5 }
| pattern ARROW expr
{ [($1, $3)] }
;
pattern:
| LPAREN pattern RPAREN {$2}
| VAR {PVar $1}
| UNIT {PUnit}
| INT {PInt (int_of_string $1)}
| TRUE {PBool true}
| FALSE {PBool false}
| STRING {PString $1}
| CONSTR pattern %prec CONSTR
{PVariant ($1,$2)}
| pattern COMMA pattern %prec COMMA
{PPair ($1,$3)}
;
typ:
| TUNIT {TUnit} | TINT {TInt} | TBOOL {TBool} | TSTRING {TString}
| TVAR { TAlpha $1 }
| typ ARROW typ { TArrow ($1,$3) }
| typ MULT typ { TStar ($1,$3) }
| VAR { TVariant ([], $1) }
| typ VAR { TVariant ([$1], $2) }
| LPAREN typ RPAREN { $2 }
| LPAREN typ_list RPAREN VAR %prec TCONS
{ TVariant ($2, $4) }
;
typ_list:
| typ {[$1]}
| typ_list COMMA typ {$1@[$3]}
;
variant_spec:
| TYPE tvar_list VAR EQ constr_list
{ {vars = $2; name = $3; constructors = $5} }
| TYPE tvar_list VAR EQ PIPE constr_list
{ {vars = $2; name = $3; constructors = $6} }
;
tvar_list:
| {[]}
| TVAR {[$1]}
| LPAREN tvar_list_inside RPAREN {$2}
;
tvar_list_inside:
| TVAR {[$1]}
| TVAR COMMA tvar_list_inside {$1::$3}
;
constr_list:
| CONSTR OF typ { [($1,$3)] }
| CONSTR OF typ PIPE constr_list {($1,$3)::$5}
;