-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.mly
107 lines (91 loc) · 2.64 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
%{
open Syntax
let parse_error msg = Printf.eprintf "%s\n" msg
(* ここに書いたものは,ExampleParser.mliに入らない *)
%}
%token <int> INT
%token <bool> BOOL
%token <string> ID
%token LET IN
%token PLUS TIMES MINUS DIV
%token BAND BOR NOT
%token EQ LT
%token IF THEN ELSE
%token LPAR RPAR
%token FUN ARROW
%token REC AND
%token LBRACKET RBRACKET CONS COMMA
%token MATCH WITH BAR
%token SEMISEMI
%token ERROR
%start toplevel
%type <Syntax.command> toplevel
%%
toplevel:
| expr SEMISEMI { CExp $1 }
| LET var EQ expr SEMISEMI { CDecl ($2, $4) }
| LET REC let_and_decls SEMISEMI { CRecDecl ($3) }
| error {PLErr}
;
let_and_decls:
| var var EQ expr AND let_and_decls { ($1,$2,$4) :: $6 }
| var var EQ expr { [($1,$2,$4)] }
expr:
| LET var EQ expr IN expr { ELet($2,$4,$6) }
| LET REC let_and_decls IN expr { ELetRec($3,$5) }
| IF expr THEN expr ELSE expr { EIf($2,$4,$6) }
| NOT expr { ENot($2) }
| FUN var ARROW expr { EFun($2,$4) }
| arith_expr EQ arith_expr { EEq($1,$3) }
| arith_expr LT arith_expr { ELt($1,$3) }
| MATCH expr WITH cases { EMatch($2, $4) }
| MATCH expr WITH BAR cases { EMatch($2, $5) }
| list_expr { $1 }
;
cases:
| pattern ARROW expr BAR cases { ($1, $3) :: $5 }
| pattern ARROW expr { [($1, $3)] }
;
pattern:
| atomic_pattern CONS pattern { PCons($1,$3) }
| atomic_pattern { $1 }
;
atomic_pattern:
| INT { PInt($1) }
| BOOL { PBool($1) }
| var { PVar($1) }
| LPAR pattern COMMA pattern RPAR { PPair($2, $4) }
| LBRACKET RBRACKET { PNil }
| LPAR pattern RPAR { $2 }
;
list_expr:
| arith_expr CONS list_expr { ECons($1, $3) }
| arith_expr { $1 }
;
arith_expr:
| arith_expr PLUS factor_expr { EAdd($1,$3) }
| arith_expr BOR factor_expr { EOr($1,$3) }
| arith_expr MINUS factor_expr { ESub($1,$3) }
| factor_expr { $1 }
;
factor_expr:
| factor_expr TIMES atomic_expr { EMul($1,$3) }
| factor_expr BAND atomic_expr { EAnd($1,$3) }
| factor_expr DIV atomic_expr { EDiv($1,$3) }
| app_expr { $1 }
;
app_expr:
| app_expr atomic_expr { EApp($1, $2) }
| atomic_expr { $1 }
;
atomic_expr:
| INT { EConstInt($1) }
| BOOL { EConstBool($1) }
| LPAR expr COMMA expr RPAR { EPair($2, $4) }
| LBRACKET RBRACKET { ENil }
| ID { EVar($1) }
| LPAR expr RPAR { $2 }
;
var:
| ID { $1 }
;