This commit is contained in:
Adrien Guatto 2023-09-27 18:49:08 +02:00
parent d005428cf1
commit abf23ab803
10 changed files with 128 additions and 0 deletions

6
cours/cours-02/ast.ml Normal file
View file

@ -0,0 +1,6 @@
type e =
| EInt of int (** Ex: "42", "31" *)
| EVar of string (** Ex: "x", "y", "foo" *)
| EPlus of e * e (** Ex: "1 + 2", "2 * 3 + 4" *)
| EMult of e * e (** Ex: "1 * 2", "(1 + 2) * 3" *)
| ESum of string * e * e * e (** Ex: "sum (x, 1, 10, x * x)" *)

7
cours/cours-02/dune Normal file
View file

@ -0,0 +1,7 @@
(executable
(name marthe)
)
(ocamllex (modules lexer))
(menhir (modules parser) (infer true) (flags --explain))

View file

@ -0,0 +1,3 @@
(lang dune 2.2)
(using menhir 2.1)

15
cours/cours-02/lexer.mll Normal file
View file

@ -0,0 +1,15 @@
{
(* Prelude *)
open Parser
}
rule token = parse
| ['0'-'9']+ as x { INT (int_of_string x) }
| '+' { PLUS }
| '*' { STAR }
| ' ' { token lexbuf }
| eof { EOF }
{
(* Postlude *)
}

55
cours/cours-02/marthe.ml Normal file
View file

@ -0,0 +1,55 @@
open Ast
let parse lexbuf = Parser.phrase Lexer.token lexbuf
let interpret : e -> int =
(* Le paramètre [env] est une liste associative contenant la valeur associée
aux indices de sommation.
La fonction d'évaluation est définie par cas sur la forme de l'arbre. *)
let rec aux env = function
(* Pour évaluer une expression de la forme "e1 + e2", on évalue [e1] en un
entier, on évalue [e2] en un autre entier, puis on fait la somme des deux
entiers. *)
| EPlus (e1, e2) -> aux env e1 + aux env e2
(* Même raisonnement pour la multiplication. *)
| EMult (e1, e2) -> aux env e1 * aux env e2
(* Une expression qui est un entier s'évalue en cet entier. *)
| EInt x -> x
(* Pour évaluer une expression de la forme "sum (x, start, stop, body)". *)
| ESum (x, start, stop, body) ->
(* On évalue [start]. *)
let vstart = aux env start
(* On évalue [stop]. *)
and vstop = aux env stop
in
(* On itère sur toutes les valeurs [i] de [start] à [stop] et on accumule
les sommes intermédiaires dans la variable [accu]. *)
let rec iter i accu =
if i > vstop then
accu
else
(* L'évaluation de [body] se fait dans un environnement où l'indice
[x] est associé à la valeur [i]. *)
iter (i + 1) (accu + aux ((x, i) :: env) body)
in
iter vstart 0
(* Une expression qui est variable s'évalue en la valeur associée à cette
variable dans l'environnement. *)
| EVar x ->
List.assoc x env
in
aux []
let process filename =
let cin = open_in filename in
let ast = parse (Lexing.from_channel cin) in
let x = interpret ast in
Printf.printf "Result: %d\n%!" x
let main =
Array.iteri (fun i filename -> if i >= 1 then process filename) Sys.argv

33
cours/cours-02/parser.mly Normal file
View file

@ -0,0 +1,33 @@
%{
(* Prelude *)
open Ast
%}
(* Zone des déclarations *)
%token EOF PLUS STAR
%token<int> INT
%start<Ast.e> phrase
%%
(* Cette grammaire a un conflit avancer-réduire. Comment le régler ? *)
(* Ici on écrit les règles de grammaire. *)
phrase: e=expression EOF
{
e
}
expression: x=INT
{
EInt x
}
| lhs=expression PLUS rhs=expression
{
EPlus (lhs, rhs)
}
| lhs=expression STAR rhs=expression
{
EMult (lhs, rhs)
}

BIN
cours/cours-flap.pdf Normal file

Binary file not shown.

BIN
cours/cours-parsing.pdf Normal file

Binary file not shown.

View file

@ -31,3 +31,12 @@
https://listes.u-paris.fr/wws/info/m1.2023.compilation.info https://listes.u-paris.fr/wws/info/m1.2023.compilation.info
*** TODO Prochain séance de cours *** TODO Prochain séance de cours
- Finir la gestion des commentaires dans ~marthe.ml~. - Finir la gestion des commentaires dans ~marthe.ml~.
* Cours 02 <2023-09-27>
** Analyse syntaxique appliquée
Voir les [[file:cours-parsing.pdf][transparents]].
** Aperçu de flap
Voir les [[file:cours-flap.pdf][transparents]].
** La semaine prochaine
- En TP : une initiation à Menhir.
- En cours : le démarrage du jalon 1.

Binary file not shown.