Repository navigation
Expand file tree
/
Copy pathparser.mly
More file actions
204 lines (181 loc) · 5.45 KB
/
Copy pathparser.mly
File metadata and controls
204 lines (181 loc) · 5.45 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
%{
open Ast
let table_type = ["i32",Tint;
"bool",Tbool;
]
let find_type t = try List.assoc t table_type with _ -> Tstruct(t)
exception Empty_block
exception Empty_ins
exception Syntax_Error
let rec remove_null_instruction p =
match p with
| [] -> []
| (Inothing) :: rest -> remove_null_instruction rest
| (_ as t):: rest -> t :: (remove_null_instruction rest)
let return_type l = let t = List.concat l in
let rev_t = List.rev t in
if (List.length t) = 0 then CBlock([])
else
(let x = List.hd rev_t in
match x with
| Inothing -> CBlock (remove_null_instruction t)
| Iexpr e -> CFullBlock(remove_null_instruction (List.rev (List.tl rev_t)),e)
| _ -> raise Syntax_Error)
%}
%token <int> CST
%token <string> IDENT
%token LEFTPAR RIGHTPAR BEGIN END COMMA SEMICOLON
%token FUN ELSE FALSE IF LET MUT RETURN STRUCT TRUE WHILE
%token ASSIGN
%token OR
%token AND
%token EQUAL GQ GEQ LQ LEQ NE
%token PLUS MINUS TIMES DIV MOD
%token EXCL
%token ARROW
%token <string> CHAIN
%token COLON
%token EOF
%token POINTER
%token LEFTSQ RIGHTSQ
%token LEN
%token POINT
/* Les priorités et associativités des tokens */
%right ASSIGN
%left OR
%left AND
%nonassoc EQUAL GQ GEQ LQ LEQ NE
%left PLUS MINUS
%left TIMES DIV MOD
%nonassoc unary
%nonassoc length
%nonassoc st
/* Point d'entrée de la grammaire */
%start prog
/* Type des valeurs renvoyées par l'analyseur syntaxique */
%type <Ast.program> prog
%%
prog:
decls = decl* EOF
{ decls }
;
typ:
| t = IDENT { find_type t }
| name = IDENT LQ t = typ GQ { Tstructgeneric(name,t) }
| POINTER t = typ {Tref(t)}
| POINTER MUT t = typ {Tmut(t)}
;
argument:
| MUT name = IDENT COLON typs = typ { { name = name; types = typs; mut = true} }
| name = IDENT COLON typs = typ { { name = name; types = typs; mut = false} }
;
struct_argument:
name = IDENT COLON typs = typ
{ { name = name;
types = typs; } }
;
decl:
| STRUCT s = IDENT BEGIN t = separated_list(COMMA,struct_argument) END
{ let st = { name = s;
defs = t; }
in Decl_struct(st) }
| FUN f = IDENT LEFTPAR para = separated_list(COMMA, argument) RIGHTPAR ARROW t = typ bl = block
{ let fn = {
name = f;
defs = para;
return = t;
body = bl
}
in Decl_fun(fn) }
| FUN f = IDENT LEFTPAR para = separated_list(COMMA, argument) RIGHTPAR bl = block
{ let fn = {
name = f;
defs = para;
return = Tnull;
body = bl;
}
in Decl_fun(fn) }
;
block:
| BEGIN ins = separated_list(SEMICOLON,instruction_in_general) END { return_type ins }
;
assign:
name = IDENT COLON e = expr {(name , e)}
;
instruction_without_block:
| {Inothing}
| e = expr {Iexpr(e)}
| LET MUT id = IDENT ASSIGN e = expr {ImutExAssign(id , e)}
| LET id = IDENT ASSIGN e = expr {IexAssign(id,e)}
| LET MUT id = IDENT ASSIGN idstruct = IDENT BEGIN var = separated_list(COMMA, assign) END
{ImutStAssign(id, idstruct, var)}
| LET id = IDENT ASSIGN idstruct = IDENT BEGIN var = separated_list(COMMA, assign) END
{IstAssign(id, idstruct, var)}
| RETURN {IreturnNull}
| RETURN e = expr {Ireturn(e)}
;
instruction_with_block:
| WHILE e = expr bl = block {Iwhile(e,bl)}
| i = condition {Icond(i)}
;
instruction_in_general:
bad_instruction = instruction_with_block* good_instruction = instruction_without_block {bad_instruction @ (good_instruction::[])}
;
(*instruction:
| SEMICOLON {Inothing}
| e = expr SEMICOLON {Iexpr(e)}
| LET MUT id = IDENT ASSIGN e = expr SEMICOLON {ImutExAssign(id , e)}
| LET id = IDENT ASSIGN e = expr SEMICOLON {IexAssign(id,e)}
| LET MUT id = IDENT ASSIGN idstruct = IDENT BEGIN var = separated_list(COMMA, assign) END SEMICOLON
{ImutStAssign(id, idstruct, var)}
| LET id = IDENT ASSIGN idstruct = IDENT BEGIN var = separated_list(COMMA, assign) END SEMICOLON
{IstAssign(id, idstruct, var)}
| WHILE e = expr bl = block {Iwhile(e,bl)}
| RETURN SEMICOLON {IreturnNull}
| RETURN e = expr SEMICOLON {Ireturn(e)}
| i = condition {Icond(i)}
;*)
condition:
| IF e = expr bl = block {Cif(e, bl, CBlock([]))}
| IF e = expr bl1 = block ELSE bl2 = block { Cif(e, bl1, bl2) }
| IF e = expr bl = block ELSE i = condition { CnestedIf(e, bl, i) }
;
expr:
| i = CST { Econst(i) }
| TRUE { Ebool(true) }
| FALSE { Ebool(false) }
| id = IDENT { Evar(id) }
| bl = block {Eblock(bl)}
| e1 = expr op = bop e2 = expr { Ebinop(op,e1,e2) }
| op = unop e = expr %prec unary { Eunop(op,e) }
| e1 = expr POINT id = IDENT %prec st { Estruct(e1,id) }
| e = expr POINT LEN LEFTPAR RIGHTPAR %prec length { Elength(e) }
| e1 = expr LEFTSQ e2 = expr RIGHTSQ { Eindex(e1,e2) }
| t = IDENT EXCL LEFTSQ e = separated_list(COMMA,expr) RIGHTSQ { if t = "vec" then Evector(e) else raise Syntax_Error}
| e1 = IDENT LEFTPAR e = separated_list(COMMA,expr) RIGHTPAR {Ecall(e1,e)}
| LEFTPAR e = expr RIGHTPAR {e}
| t = IDENT EXCL LEFTPAR s = CHAIN RIGHTPAR { if t = "print" then Eprint(s) else raise Syntax_Error}
(*à complet*)
;
%inline bop:
| PLUS {Badd}
| MINUS {Bsub}
| TIMES {Bmul}
| DIV {Bdiv}
| MOD {Bmod}
| EQUAL {Beq}
| NE {Bneq}
| LQ {Blt}
| LEQ {Ble}
| GQ {Bgt}
| GEQ {Bge}
| AND {Band}
| OR {Bor}
| ASSIGN {Bassign}
;
%inline unop:
| MINUS {Uneg}
| EXCL {Unot}
| TIMES {Unstar}
| POINTER {Unp}
| POINTER MUT {Unmutp}