2022-12-06 20:39:15 +01:00
|
|
|
%{
|
|
|
|
open Ast
|
|
|
|
open Ast.Syntax
|
|
|
|
%}
|
|
|
|
|
|
|
|
%token <int> Lint
|
2022-12-08 21:30:39 +01:00
|
|
|
%token <bool> Lbool
|
2022-12-11 03:35:52 +01:00
|
|
|
%token <string> Lstr
|
2022-12-08 19:55:22 +01:00
|
|
|
%token <Ast.type_t> Ltype
|
|
|
|
%token <string> Lvar
|
2022-12-09 14:14:33 +01:00
|
|
|
%token Lend Lassign Lsc Lreturn
|
2022-12-10 01:55:15 +01:00
|
|
|
%token Lbracedeb Lbracefin
|
|
|
|
%token Lpardeb Lparfin Lcomma
|
2022-12-14 00:01:28 +01:00
|
|
|
%token Ladd Lsub Lmul Ldiv Lbigger Lsmaller Leq Lneq
|
2022-12-13 17:10:14 +01:00
|
|
|
%token Lif Lelse Lwhile
|
2022-12-09 14:45:59 +01:00
|
|
|
|
2022-12-14 00:01:28 +01:00
|
|
|
%left Ladd Lsub Lmul Ldiv Lbigger Lsmaller Leq Lneq
|
2022-12-06 20:39:15 +01:00
|
|
|
|
2022-12-10 17:34:56 +01:00
|
|
|
%left Lbracedeb Lparfin Lbracefin Lreturn
|
2022-12-11 03:35:52 +01:00
|
|
|
%left Ltype Lbool Lint Lvar Lstr
|
2022-12-13 17:10:14 +01:00
|
|
|
%left Lif Lwhile
|
2022-12-10 17:34:56 +01:00
|
|
|
|
2022-12-06 20:39:15 +01:00
|
|
|
%start prog
|
|
|
|
|
2022-12-10 01:55:15 +01:00
|
|
|
%type <Ast.Syntax.block> block
|
|
|
|
%type <Ast.Syntax.prog> prog
|
2022-12-10 13:49:05 +01:00
|
|
|
%type <Ast.Syntax.args> args_ident
|
2022-12-10 01:55:15 +01:00
|
|
|
%type <Ast.Syntax.expr list> args_expr
|
2022-12-06 20:39:15 +01:00
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
prog:
|
2022-12-10 01:55:15 +01:00
|
|
|
/* Liste des définitions de fonction */
|
|
|
|
| i = def ; b = prog { i @ b }
|
2022-12-09 22:14:18 +01:00
|
|
|
/* Fin de programme */
|
2022-12-08 19:55:22 +01:00
|
|
|
| Lend { [] }
|
2022-12-09 22:14:18 +01:00
|
|
|
|
2022-12-10 01:55:15 +01:00
|
|
|
def:
|
|
|
|
/* Définition fonction : type fonction (args) block */
|
|
|
|
| t = Ltype
|
|
|
|
; f = Lvar
|
|
|
|
; a = args_ident
|
|
|
|
; b = block {
|
|
|
|
[ Func { func = f ; type_t = t ; args = a ; code = b ; pos = $startpos(f) } ]
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Définition fonction : type fonction () block */
|
|
|
|
| t = Ltype
|
|
|
|
; f = Lvar
|
|
|
|
; Lpardeb
|
|
|
|
; Lparfin
|
|
|
|
; b = block {
|
|
|
|
[ Func { func = f ; type_t = t ; args = [] ; code = b ; pos = $startpos(f) } ]
|
|
|
|
}
|
|
|
|
|
|
|
|
args_ident:
|
|
|
|
/* ( */
|
|
|
|
| Lpardeb ; s = args_ident { s }
|
|
|
|
|
2022-12-10 16:06:13 +01:00
|
|
|
/* type a, ... */
|
2022-12-10 13:49:05 +01:00
|
|
|
| t = Ltype ; a = arg_ident ; Lcomma ; s = args_ident { Arg { type_t = t
|
|
|
|
; name = a
|
|
|
|
} :: s }
|
2022-12-10 01:55:15 +01:00
|
|
|
|
2022-12-10 16:06:13 +01:00
|
|
|
/* type c) */
|
2022-12-10 13:49:05 +01:00
|
|
|
| t = Ltype ; a = arg_ident ; Lparfin { [ Arg { type_t = t
|
|
|
|
; name = a } ] }
|
2022-12-10 01:55:15 +01:00
|
|
|
|
2022-12-10 01:59:11 +01:00
|
|
|
/* ) */
|
2022-12-10 01:55:15 +01:00
|
|
|
| Lparfin { [] }
|
|
|
|
|
|
|
|
arg_ident:
|
|
|
|
/* Argument */
|
2022-12-10 13:49:05 +01:00
|
|
|
| a = Lvar { a }
|
2022-12-10 01:55:15 +01:00
|
|
|
|
|
|
|
block:
|
|
|
|
/* { */
|
|
|
|
| Lbracedeb ; b = block { b }
|
|
|
|
|
2022-12-10 15:50:34 +01:00
|
|
|
/* instr ... */
|
2022-12-10 01:55:15 +01:00
|
|
|
| i = instr ; b = block { i @ b }
|
|
|
|
|
|
|
|
/* } */
|
|
|
|
| Lbracefin { [] }
|
2022-12-06 20:39:15 +01:00
|
|
|
;
|
|
|
|
|
2022-12-08 19:55:22 +01:00
|
|
|
instr:
|
2022-12-10 15:50:34 +01:00
|
|
|
/* return x; */
|
2022-12-10 01:55:15 +01:00
|
|
|
| Lreturn ; e = expr ; Lsc { [ Return { expr = e ; pos = $startpos } ] }
|
2022-12-09 22:14:18 +01:00
|
|
|
|
2022-12-13 16:09:25 +01:00
|
|
|
/* return; */
|
|
|
|
| Lreturn ; Lsc {
|
|
|
|
[ Return { expr = Val { value = Void ; pos = $startpos }
|
|
|
|
; pos = $startpos } ]
|
|
|
|
}
|
|
|
|
|
2022-12-10 15:50:34 +01:00
|
|
|
/* type v; */
|
2022-12-10 01:55:15 +01:00
|
|
|
| t = Ltype ; v = Lvar ; Lsc {
|
2022-12-09 14:45:59 +01:00
|
|
|
[ Decl { name = v ; type_t = t ; pos = $startpos(t) } ]
|
2022-12-08 19:55:22 +01:00
|
|
|
}
|
2022-12-09 22:14:18 +01:00
|
|
|
|
2022-12-10 15:50:34 +01:00
|
|
|
/* type v = e; */
|
2022-12-10 01:55:15 +01:00
|
|
|
| t = Ltype ; v = Lvar ; Lassign ; e = expr ; Lsc
|
2022-12-09 22:33:08 +01:00
|
|
|
{ [ Decl { name = v ; type_t = t ; pos = $startpos(t) }
|
2022-12-09 14:45:59 +01:00
|
|
|
; Assign { var = v ; expr = e ; pos = $startpos(v) } ]
|
2022-12-08 19:55:22 +01:00
|
|
|
}
|
2022-12-09 22:14:18 +01:00
|
|
|
|
2022-12-10 15:50:34 +01:00
|
|
|
/* v = e; */
|
2022-12-10 01:55:15 +01:00
|
|
|
| v = Lvar ; Lassign ; e = expr ; Lsc {
|
2022-12-09 17:04:33 +01:00
|
|
|
[ Assign { var = v ; expr = e ; pos = $startpos($2) } ]
|
|
|
|
}
|
2022-12-08 19:55:22 +01:00
|
|
|
|
2022-12-10 16:06:13 +01:00
|
|
|
/* e; */
|
|
|
|
| e = expr ; Lsc {
|
|
|
|
[ Do { expr = e ; pos = $startpos} ]
|
2022-12-10 01:55:15 +01:00
|
|
|
}
|
|
|
|
|
2022-12-13 16:09:25 +01:00
|
|
|
/* if (e) {} else {} */
|
|
|
|
| Lif ; Lpardeb ; e = expr ; Lparfin ; b1 = block ; Lelse ; b2 = block {
|
|
|
|
[ Cond { expr = e ; if_b = b1 ; else_b = b2 ; pos = $startpos } ]
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if (e) {} */
|
|
|
|
| Lif ; Lpardeb ; e = expr ; Lparfin ; b = block {
|
|
|
|
[ Cond { expr = e ; if_b = b ; else_b = [] ; pos = $startpos } ]
|
|
|
|
}
|
|
|
|
|
2022-12-13 17:10:14 +01:00
|
|
|
/* while (e) {} */
|
|
|
|
| Lwhile ; Lpardeb ; e = expr ; Lparfin ; b = block {
|
|
|
|
[ Loop { expr = e ; block = b ; pos = $startpos } ]
|
|
|
|
}
|
|
|
|
|
2022-12-06 20:39:15 +01:00
|
|
|
expr:
|
2022-12-09 22:14:18 +01:00
|
|
|
/* int */
|
2022-12-08 19:55:22 +01:00
|
|
|
| n = Lint {
|
|
|
|
Val { value = Int (n) ; pos = $startpos(n) }
|
|
|
|
}
|
2022-12-09 22:14:18 +01:00
|
|
|
|
|
|
|
/* bool */
|
2022-12-08 21:30:39 +01:00
|
|
|
| b = Lbool {
|
|
|
|
Val { value = Bool (b) ; pos = $startpos(b) }
|
|
|
|
}
|
2022-12-09 22:14:18 +01:00
|
|
|
|
2022-12-11 03:35:52 +01:00
|
|
|
/* string */
|
|
|
|
| s = Lstr {
|
|
|
|
Val { value = Str (s) ; pos = $startpos(s) }
|
|
|
|
}
|
|
|
|
|
2022-12-09 22:14:18 +01:00
|
|
|
/* Variable */
|
2022-12-08 19:55:22 +01:00
|
|
|
| v = Lvar {
|
|
|
|
Var { name = v ; pos = $startpos(v) }
|
|
|
|
}
|
2022-12-09 22:14:18 +01:00
|
|
|
|
|
|
|
/* e + e */
|
2022-12-09 14:45:59 +01:00
|
|
|
| a = expr ; Ladd ; b = expr {
|
|
|
|
Call { func = "%add" ; args = [ a ; b ] ; pos = $startpos($2) }
|
|
|
|
}
|
2022-12-09 22:14:18 +01:00
|
|
|
|
|
|
|
/* e - e */
|
2022-12-09 16:39:44 +01:00
|
|
|
| a = expr ; Lsub ; b = expr {
|
|
|
|
Call { func = "%sub" ; args = [ a ; b ] ; pos = $startpos($2) }
|
|
|
|
}
|
2022-12-09 22:14:18 +01:00
|
|
|
|
|
|
|
/* e * e */
|
2022-12-09 16:12:32 +01:00
|
|
|
| a = expr ; Lmul ; b = expr {
|
|
|
|
Call { func = "%mul" ; args = [ a ; b ] ; pos = $startpos($2) }
|
|
|
|
}
|
2022-12-09 22:14:18 +01:00
|
|
|
|
|
|
|
/* e / e */
|
2022-12-09 16:39:44 +01:00
|
|
|
| a = expr ; Ldiv ; b = expr {
|
|
|
|
Call { func = "%div" ; args = [ a ; b ] ; pos = $startpos($2) }
|
|
|
|
}
|
2022-12-10 16:06:13 +01:00
|
|
|
|
2022-12-13 17:10:14 +01:00
|
|
|
/* e < e */
|
2022-12-14 00:01:28 +01:00
|
|
|
| a = expr ; Lsmaller ; b = expr {
|
2022-12-13 17:10:14 +01:00
|
|
|
Call { func = "%big" ; args = [ a ; b ] ; pos = $startpos($2) }
|
|
|
|
}
|
|
|
|
|
2022-12-14 00:01:28 +01:00
|
|
|
/* e > e */
|
|
|
|
| a = expr ; Lbigger ; b = expr {
|
|
|
|
Call { func = "%sml" ; args = [ a ; b ] ; pos = $startpos($2) }
|
|
|
|
}
|
|
|
|
|
|
|
|
/* e == e */
|
|
|
|
| a = expr ; Leq ; b = expr {
|
|
|
|
Call { func = "%equ" ; args = [ a ; b ] ; pos = $startpos($2) }
|
|
|
|
}
|
|
|
|
|
|
|
|
/* e != e */
|
|
|
|
| a = expr ; Lneq ; b = expr {
|
|
|
|
Call { func = "%neq" ; args = [ a ; b ] ; pos = $startpos($2) }
|
|
|
|
}
|
|
|
|
|
2022-12-10 17:36:34 +01:00
|
|
|
/* function(a */
|
2022-12-10 16:06:13 +01:00
|
|
|
| f = Lvar ; Lpardeb ; a = args_expr {
|
|
|
|
Call { func = f ; args = a ; pos = $startpos(a) }
|
|
|
|
}
|
2022-12-06 20:39:15 +01:00
|
|
|
;
|
2022-12-10 16:06:13 +01:00
|
|
|
|
|
|
|
args_expr:
|
|
|
|
/* a, ... */
|
|
|
|
| a = expr ; Lcomma ; s = args_expr { a :: s }
|
|
|
|
|
|
|
|
/* c) */
|
|
|
|
| a = expr ; Lparfin { [ a ] }
|
|
|
|
|
|
|
|
/* ) */
|
|
|
|
| Lparfin { [] }
|