This repository has been archived by the owner on Feb 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathparser.mly
140 lines (114 loc) · 2.87 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
(*
%token <float> FLOAT
%token <binary> BINARY
%token LEFT_BRACKET RIGHT_BRACKET
%token ASSIGN
%token LET
Keyword version:
if boolExpr then expr else expr
Braces version:
if boolExpr { expr } else { expr }
Pro Imbrication simplifiée.
match expr {
| pattern -> expr
}
match expr with
|
*)
%token <int> INT
%token TRUE FALSE
%token <string> ID
%token LEFT_PARENS RIGHT_PARENS
%token LEFT_BRACE RIGHT_BRACE
%token SEMICOLON
(* %token EOL *)
%token IF ELSE
%token WHEN
%token UNIT
%token LET
%token IN
%token END
%token FUNCTION
%token LAMBDA
%token DIVIDE PLUS MINUS TIMES MODULO
%token LESSER_EQUAL GREATER_EQUAL
%token GREATER LESSER
%token NOT_EQUALS EQUALS
%token EOF
%nonassoc SEMICOLON
%nonassoc EQUALS
%left PLUS MINUS
%left TIMES DIVIDE MODULO
%left LESSER_EQUAL GREATER_EQUAL GREATER LESSER NOT_EQUALS
(*
%token ASSIGN
*)
(*
Precedency
0: *
1: /
2: +
4: -
*)
%start <Ast.expr option> program
%%
program:
| EOF { None };
| e = expression EOF { Some e };
(*
stm:
| stm SEMICOLON stm
*)
%inline binop:
| PLUS { Ast.Add }
| MINUS { Ast.Sub }
| TIMES { Ast.Mult }
| DIVIDE { Ast.Div }
| MODULO { Ast.Mod }
| LESSER_EQUAL { Ast.Ge }
| GREATER_EQUAL { Ast.Le }
| GREATER { Ast.Gt }
| LESSER { Ast.Le }
| NOT_EQUALS { Ast.Neq }
| EQUALS { Ast.Eq }
fun_args:
| (* end of args *) { [] }
| arg = ID; args = fun_args
{ arg :: args }
(*
(* { <expression> } *)
| LEFT_BRACE; e = expression; RIGHT_BRACE
{ e }
(* let <pattern> = <expression in <expression> end *)
*)
expression:
| UNIT { Ast.Unit }
| TRUE { Ast.True }
| FALSE { Ast.False }
| i = INT { Ast.Int (i) }
| id = ID { Ast.Id (id) }
| left = expression; op = binop; right = expression
{ Ast.Op (op, left, right) }
(* ( <expression> ) *)
| LEFT_PARENS; e = expression ;RIGHT_PARENS
{ e }
(* if <expression> { <expression> } else { <expression> } *)
| IF; predicat = expression; LEFT_BRACE; ifExpr = expression; RIGHT_BRACE;
ELSE; LEFT_BRACE; elseExpr = expression; RIGHT_BRACE
{ Ast.If (predicat, ifExpr, elseExpr) }
(* when <expr> { <expression> } *)
| WHEN; test = expression; LEFT_BRACE; whenExpr = expression; RIGHT_BRACE
{ Ast.If (test, whenExpr, Ast.Unit) }
(* let <identifiant> = <expression> in expression end *)
| LET; id = ID; EQUALS; dec = expression; IN; body = expression; END
{ Ast.Let (id, dec, body) }
(* <expression>; <expression> *)
| left = expression; SEMICOLON; right = expression
{ Ast.Seq (left, right) }
(* fun <identifiant> <args_list> { <expression> } *)
| FUNCTION; id = ID; args = fun_args; LEFT_BRACE;
fun_body = expression; RIGHT_BRACE
{ Ast.Fun (id, args, fun_body)}
(* lambda: fn <args_list> { <expression> } *)
| LAMBDA; args = fun_args; LEFT_BRACE; fun_body = expression; RIGHT_BRACE
{ Ast.Lambda (args, fun_body) }