Repository navigation
Expand file tree
/
Copy pathparser.mly
More file actions
205 lines (185 loc) · 3.84 KB
/
Copy pathparser.mly
File metadata and controls
205 lines (185 loc) · 3.84 KB
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
%{
open Ast
%}
/* tokens */
%token <Ast.constant> CST
%token <Ast.binop> CMP
%token <string> IDENT
%token <string> STRING
%token ELSE FN IF LET RETURN STRUCT WHILE
%token LEN VEC EOF PRINT
%token ARROW EQUAL BLT BGT
%token PLUS MINUS STAR DIV MOD
%token AND OR MUT BORR NOT
%token LP RP LSQ RSQ COMMA POINT COLON SEMICOLON LB RB
/* ordre de priorite */
%right EQUAL
%left OR
%left AND
%nonassoc CMP BLT BGT
%left PLUS MINUS
%left STAR DIV MOD
%nonassoc NOT unary_minus unary_star BORR MUT
%nonassoc LSQ
%nonassoc POINT
/* Start the parser at the file constructor */
%start parse_file
%type <Ast.sfile> parse_file
%%
// a file is a list of declarations that ends with EOF
parse_file:
d = list(decl) EOF
{d}
;
// a declaration is either a function or a structure
decl:
| FN f = decl_fun
{Dfun f}
| STRUCT d = decl_struct
{Dstruct d}
;
// a structure is an identifier, `{`, body, `}`
decl_struct:
name = ident
LB
// the body is a sequence of identifiers:value ending with comma
body = separated_list(COMMA,separated_pair (ident,COLON,typ))
RB
{ { name = name;
body = body;
localisation = $startpos,$endpos} }
;
// a function is a name `(` arguments `)` -> type {...}
decl_fun:
name = ident
LP
// arguments are comma separated
formals = separated_list(COMMA,arg)
RP
// declaring the function type in rust is optional
t = option(preceded(ARROW,typ))
body = block
{ { name = name;
formals = (formals,t);
body = body;
localisation = $startpos,$endpos } }
;
// an argument is mut identifier: type
arg:
// the mut is optional
mut = boption(MUT) i = ident COLON t=typ
{ (mut,i),t }
;
// a type could have several syntax
typ:
t = my_type
{ {my_type = t;
localisation = $startpos,$endpos} }
;
my_type:
| i=ident // identifier
{ Tident i }
| i=ident BLT t=typ BGT // <identifier>
{ Tidtyp (i,t) }
| BORR t = typ // &typ
{ Tref t }
| BORR MUT t = typ // &mut typ
{ Trefmut t }
;
// a block body ...
blockbody :
| e=option(expr) // empty or contains expressions
{ ([],e) }
| s=stmt b=blockbody // statement ...
{ (s::(fst b),snd b) }
;
// a block {...}
block:
| LB body=blockbody RB
{body}
;
stmt:
| SEMICOLON // ;
{ Snone }
| e = expr SEMICOLON // exp;
{ Sexpr e }
| LET boolean = boption(MUT) name = ident EQUAL e = expr SEMICOLON // let mut identifier = exp;
{ Sletv((boolean,name),e) }
| LET boolean = boption(MUT) name = ident EQUAL i = ident LB
l = separated_list(COMMA,separated_pair(ident, COLON, expr)) RB SEMICOLON
{ Slets((boolean,name),i,l) } // let mut identifier = identifier {identifier:exp, ...};
| WHILE e = expr b = block // while e {...}
{ Swhile(e,b) }
| RETURN e = option(expr) SEMICOLON // return e;
{ Sret e }
| IF e = ifcmp // if
{ Sif e }
;
expression:
| c = CST
{ Ecst c }
| i = ident
{ Eident i }
| MINUS e1 = expr %prec unary_minus // -e
{ Eunop(Uneg,e1) }
| STAR e1 = expr %prec unary_star // *e
{ Eunop(Uderef,e1) }
| u=unary e1=expr
{ Eunop(u,e1) }
| e1 = expr o = binop e2 = expr
{ Ebinop(o,e1,e2) }
| e=expr POINT i=ident
{ Estruct(e,i) }
| e=expr POINT LEN LP RP
{ Elen e }
| e1=expr LSQ e2=expr RSQ
{ Eget(e1,e2) }
| i=ident LP le=separated_list(COMMA,expr) RP
{ Efun(i,le) }
| VEC NOT LSQ le=separated_list(COMMA,expr) RSQ
{ Evect le }
| PRINT NOT LP s=STRING RP
{ Eprint s }
| b=block
{ Eblock b }
| LP e=expr RP
{ Eparenthese e }
;
expr:
| d=expression
{ {expression = d;
localisation = $startpos,$endpos} }
;
ifcmp:
| e=expr b=block t=option(preceded(ELSE,elsecmp))
{e,b,t}
;
elsecmp:
| b = block
{Cblock b}
| IF i = ifcmp
{Cif i}
;
%inline binop:
| PLUS { Badd }
| MINUS { Bsub }
| STAR { Bmul }
| DIV { Bdiv }
| MOD { Bmod }
| c=CMP { c }
| BLT { Blt }
| BGT { Bgt }
| AND { Band }
| OR { Bor }
| EQUAL { Baff }
;
%inline unary:
| NOT {Unot}
| BORR MUT {Umut}
| BORR {Uborr}
;
ident:
| id = IDENT {id}
| PRINT {"print"}
| VEC {"vec"}
;