Cours 02
This commit is contained in:
parent
d005428cf1
commit
abf23ab803
10 changed files with 128 additions and 0 deletions
6
cours/cours-02/ast.ml
Normal file
6
cours/cours-02/ast.ml
Normal 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
7
cours/cours-02/dune
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
(executable
|
||||||
|
(name marthe)
|
||||||
|
)
|
||||||
|
|
||||||
|
(ocamllex (modules lexer))
|
||||||
|
(menhir (modules parser) (infer true) (flags --explain))
|
||||||
|
|
3
cours/cours-02/dune-project
Normal file
3
cours/cours-02/dune-project
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
(lang dune 2.2)
|
||||||
|
(using menhir 2.1)
|
||||||
|
|
15
cours/cours-02/lexer.mll
Normal file
15
cours/cours-02/lexer.mll
Normal 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
55
cours/cours-02/marthe.ml
Normal 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
33
cours/cours-02/parser.mly
Normal 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
BIN
cours/cours-flap.pdf
Normal file
Binary file not shown.
BIN
cours/cours-parsing.pdf
Normal file
BIN
cours/cours-parsing.pdf
Normal file
Binary file not shown.
|
@ -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.
|
||||||
|
|
BIN
tp/tp-menhir/sujet/tp-menhir.pdf
Normal file
BIN
tp/tp-menhir/sujet/tp-menhir.pdf
Normal file
Binary file not shown.
Reference in a new issue